How to mitigate Format String Vulnerabilities
Introduction:
This article provides an overview of various techniques that can be used to mitigate Format String vulnerabilities. In addition to the mitigations that are offered by the compilers & operating systems, we will also discuss preventive measures that can be used while writing programs in languages susceptible to Format String vulnerabilities.
Learn Secure Coding Fundamentals
Techniques to prevent or mitigate Format String Vulnerabilities vulnerabilities:
Following are various common ways we can use to prevent or mitigate Format String vulnerabilities. Let us discuss each of them in detail.
- Writing securecode.
- Making use of compiler warnings
- Source code auditing
Writing secure code:
Writing secure code is the best way to prevent Format String vulnerabilities since the root cause of Format String vulnerabilities is insecure coding. When programs are written in languages that are susceptible to Format String vulnerabilities, developers must be aware of risky functions and their secure usage.
Let us consider the following code snippet as an example. printf() function is printing user supplied input and there is no format specifier used. An attacker can take advantage of this situation by passing arbitrary format specifiers.
void main(int argc, char *argv[]){
printf(argv[1]);
printf("n");
}
The following code snippet shows the secure implementation of the same program.
void main(int argc, char *argv[]){
printf("%s", argv[1]);
printf("n");
}
As you can notice in the preceding code snippet, argv[1] is properly formatted using %s within the program. Because of this, the attacker has no way to exploit this program. Following is what the attacker will see if he/she attempts to pass format specifiers to the program. Since, user input is properly formatted as string input, the user input is printed right away instead of fetching arbitrary data from the stack.
%p
$
$ ./vuln1 %x
%x
$
While this is the best way to prevent Format String vulnerabilities, it may be hard to know if legacy applications are already vulnerable to such flaws. Because of such challenges, we may have to rely on other options such as source code auditing.
Compiler warnings:
When developing new software with vulnerable functions, compilers often provide warnings and recommend to use secure alternatives of the functions used. This comes handy and developers can quickly make these changes during their development phase. The following excerpt shows the compiler warning about insecure use of printf function.
Let us once again consider the following vulnerable example.
void main(int argc, char *argv[]){
printf(argv[1]);
printf("n");
}
Compiling this program using gcc, by default throws the following warnings giving us hints about insecure usage of printf function.
vuln.c: In function ‘main’:
vuln.c:5:2: warning: format not a string literal and no format arguments [-Wformat-security]
5 | printf(argv[1]);
| ^~~~~~
$
Looking at these warnings, developers can fix the vulnerabilities and the updated code looks as follows.
void main(int argc, char *argv[]){
printf("%s", argv[1]);
printf("n");
}
If we compile the program using gcc once again, all the warnings shown earlier will not be shown anymore and this looks as follows.
$
Source Code Auditing:
The options we discussed so far are possible only if the source code is still in development mode. If the product is already developed and deployed, it could be hard to spot the vulnerabilities by going through each line of code especially when the code base is large. Scanning the source code using automated source code auditing tools is recommended in this case as many tools support programming languages like C and Format String vulnerabilities can be easily spotted.
There are several free and open source tools available to perform source code auditing. Following is the OWASP link to a list of source code auditing tools: https://owasp.org/www-community/Source_Code_Analysis_Tools
Conclusion:
We discussed some of the approaches we can use to spot format string vulnerabilities. While these approaches are categorized into different categories, the underlying root cause of Format String vulnerabilities is insecure coding. So, care must be taken when user input is passed to print functions like printf.
Learn Secure Coding Fundamentals
Sources:
- https://owasp.org/www-community/Source_Code_Analysis_Tools
- https://owasp.org/www-community/attacks/Format_string_attack
- https://www.netsparker.com/blog/web-security/format-string-vulnerabilities/