How to Write a Secure Code in C/C++ Programming Languages - Pentestmag

How to Write a Secure Code in C/C++ Programming Languages

By Alfrick Opidi of

Secure coding in C/C++ programming languages is a big deal. The two languages, which are commonly used in a multitude of applications and operating systems, are popular, flexible, and versatile. However, these languages are inherently vulnerable to exploitation.

Sometimes the solution is to code using a safer language like Java, that has suitable bounds-checking arrays and wonderful automatic garbage-collection feature. However, this is not always the best alternative, particularly if top performance is required or if C or C++ is preferred for developing the legacy code.

Therefore, to avoid shooting yourself in the foot, it is important to learn how to create a bulletproof, un-exploitable code in the C/C++ programming languages.

Vulnerabilities in C/C++ programs

One of the main reasons for the versatility of the C/C++ programming languages is ability to directly access memory manipulating functions (by means of pointers to memory locations). However, this ability is what uncovers vulnerability loopholes in the languages, and exposes C/C++ programs to buffer overflow and format string attacks.

Most of the security vulnerabilities in C/C++ programs arise from poor or careless access of memory. The memory problems normally arise because these languages do not have any mechanism for carrying out checks whether accessed memory has been allocated or initialized.

To put plainly, no implicit memory bounds checking is carried out. More so, allocation and freeing of memory is an activity that is likely to lead to errors. This way, any significant mistake can easily result in memory leaks or even crash a program. 

Buffer overflow and other related forms of attacks normally take place when a user enters more data than the program was designed to hold, consequently leading to arbitrary memory modifications. Based on how the stack is arranged, an intruder can inject arbitrary code into memory, and hence overwrite the target buffer.

A format string attack can take place when some formatting function such as printf() is not used in the right manner; that is, if some input string is used as a component of the format string.

This way, injecting parameters such as “%x” and “%n” in a format string makes way for an intruder to gain access and write to the stack.

 Tips for secure C/C++ programming

  • Desist from using strcpy() and strcat(). Substitute them with strncpy() and strncat() instead

Using strcpy() and strcat() functions in C/C++ fail to limit the length of the input string to be copied or added to the output buffer. This way, they make the programs susceptible to buffer overflow attacks. As such, it’s better you use the more secure strncpy() and strncat() functions.

Likewise, it is strongly recommended you use snprintf() and vsnprintf() functions instead of the weaker sprintf() and vsprintf() functions.

  •           Desist from using strcpy() and strcat(). Substitute them with strncpy() and strncat() instead

The strcpy() and strcat() functions also lack sufficient features to limit the length of the input data. So, using strncpy() and strncat() offer more protection against buffer overflow attacks.

  •          Observe correct usage of streadd() or strecpy()

When using the streadd() or strecpy() functions, it’s recommended you apportion a destination buffer that is at least 4X longer than the input buffer. This way, buffer overflow attacks will be avoided because when an intruder selects the input string, output buffers to the function calls streadd() or strecpy() have sufficient memory to avoid overwriting the buffer.

  •           Use precision specifiers diligently

When using string arguments for formatting functions, it’s advisable you include precision specifiers in the format strings. Examples of formatting functions used in C/C++ programming language include sprintf(), vsprintf(), scanf(), and sscanf(). Others include fscanf(), vscanf(), vsscanf() and vfscanf().

These formatting functions can be written with string arguments in their format strings. When implementing such functions, it’s advisable to define the highest possible length of such string arguments. 

Here is an example:

sprintf( buffer, "Usage: %.124s argument\n", argv[0] );

On the above example, it’s possible to copy up to 124 bytes from the associated variable argv[0]). A buffer overflow attack could occur in case a precision specifier is not used to limit the length of such a string argument.

  •           Give sufficient output buffer sizes for functions such as realpath() or getpass()

Various system functions, such as realpath() or getpass() give back a string to a buffer that the caller needs to provide. Creating output buffers of sufficient size to safely lodge the biggest possible string returned by the function is key to avoiding overrunning the buffer’s boundaries. It’s essential that you correctly determine such buffer sizes when writing C/C++ programs.

  •          Give sufficient input buffer sizes for functions such as realpath(), syslog() or getopt()

In C and C++ programming languages, some functions take string as input. Examples include realpath(), syslog() and getopt(). When such functions are injected with an extensive amount of input buffer, a buffer overflow attack can take place.

As such, a good coder will establish the greatest possible length of such input string required for a particular program and shorten input strings appropriately prior to invoking the realpath(), syslog() and getopt() functions.

  •          Perform thorough evaluation tests

It’s always a beneficial practice to use auditing tools to check for potentially dangerous functions in the C and C++ source codes. With such a tool, you can easily identify security flaws and correct them before you see a red line.

Furthermore, you can use specialized compilers that generate solid codes with comprehensive memory integrity checks. Such compilers can assist you check for memory boundary violations, memory leaks, and perform further auditing.


Besides being prone to hacking attacks, the C and the C++ are indispensable. Therefore, knowing how to design a secure, solid code in these languages is important to ensure programs function optimally as desired while providing integrity and privacy of data.

Do you have any more tips or questions on how to securely code in C/C++?

Please share your thoughts in the comment section below.

March 20, 2019
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest Most Voted
Inline Feedbacks
View all comments

© HAKIN9 MEDIA SP. Z O.O. SP. K. 2013