Uncontrolled format string
Description
This vulnerability occurs when user-controlled input is passed directly as a format string to printf-style functions (such as printf, sprintf, fprintf, or syslog) in C/C++ applications. Format strings use special conversion specifiers like %s, %x, %n, and %p to control how data is formatted and displayed. When attackers can control these format strings, they can manipulate program execution by reading from or writing to arbitrary memory locations. This is particularly dangerous because the %n specifier can write values to memory addresses, and other specifiers can leak sensitive information from the stack.
Remediation
To prevent format string vulnerabilities, implement the following security measures:
1. Never use user input directly as a format string:
// VULNERABLE - user input used as format string
char *user_input = get_user_input();
printf(user_input);
// SECURE - user input passed as argument with static format string
char *user_input = get_user_input();
printf("%s", user_input);2. Always use static, hardcoded format strings:
Ensure all format strings are defined as string literals in your code and cannot be modified by external input. The format string should always be the first argument and should be a constant.
3. Use safer alternatives when available:
// Instead of sprintf with user input: snprintf(buffer, sizeof(buffer), "%s", user_input); // Or use functions that don't interpret format strings: strcpy_s(buffer, sizeof(buffer), user_input); // Windows strlcpy(buffer, user_input, sizeof(buffer)); // BSD/macOS
4. Enable compiler warnings and protections:
Use compiler flags like
-Wformat -Wformat-security (GCC/Clang) to detect format string issues at compile time. Enable FORTIFY_SOURCE and other runtime protections where available.5. Conduct code review:
Audit all uses of printf-family functions (printf, fprintf, sprintf, snprintf, syslog, err, warn) and ensure they follow secure coding practices with static format strings and proper argument handling.