CWE-134: Use of Externally-Controlled Format String
Learn about CWE-134 (Use of Externally-Controlled Format String), its security impact, exploitation methods, and prevention guidelines.
What is Use of Externally-Controlled Format String?
• Overview: This vulnerability occurs when software uses a function that takes a format string as an argument, and that format string is sourced from an external, untrusted input. This can lead to unexpected behavior and potential security risks.
• Exploitation Methods:
- Attackers can manipulate the format string to execute arbitrary code or cause a denial of service.
- Common attack patterns include inserting format specifiers that access unintended memory locations or change program flow.
• Security Impact:
- Direct consequences include exposure of sensitive information and execution of arbitrary code.
- Potential cascading effects involve further system compromise and lateral movement within a network.
- Business impact can include data breaches, loss of customer trust, and financial losses due to system downtime or legal liabilities.
• Prevention Guidelines:
- Use fixed format strings in functions rather than accepting them from external sources.
- Validate and sanitize any input that may be used as a format string to ensure it does not contain unexpected specifiers.
- Employ security-focused tools and frameworks that help identify and mitigate format string vulnerabilities, such as static analysis tools.
Technical Details
Likelihood of Exploit:
Affected Languages: C, C++, Perl
Affected Technologies: Not specified
Vulnerable Code Example
// This code demonstrates a vulnerability where the format string
// is controlled by an external input (e.g., user input). This could
// allow an attacker to execute format string attacks, leading to
// potential information disclosure, crashes, or code execution.
#include <stdio.h>
void log_message(const char *user_input) {
// Vulnerable: user_input is used directly as a format string
printf(user_input); // Dangerous: allows format string vulnerability
printf("\n");
}
int main() {
char user_input[100];
printf("Enter a message: ");
fgets(user_input, sizeof(user_input), stdin); // Reads input from user
log_message(user_input); // Passes user input directly to the vulnerable function
return 0;
}
How to fix Use of Externally-Controlled Format String?
To fix this vulnerability, the format string should never be entirely controlled by external input. Instead, use a fixed format string and pass the user input as an argument to the format specifier. This ensures that the printf
function interprets the input as a string rather than a format string, preventing any potentially exploitable format string vulnerabilities.
Here are the steps to fix this:
- Use a fixed format string within the
printf
function. - Pass the user input as an argument to the format specifier (e.g.,
%s
).
By controlling the format string, you prevent an attacker from injecting format specifiers that could lead to security issues.
Fixed Code Example
// This code fixes the vulnerability by using a fixed format string
// and passing the user input as an argument to prevent external control
// over the format string.
#include <stdio.h>
void log_message(const char *user_input) {
// Fixed: Use a fixed format string and pass user_input as an argument
printf("%s", user_input); // Safe: user input is treated as a string
printf("\n");
}
int main() {
char user_input[100];
printf("Enter a message: ");
fgets(user_input, sizeof(user_input), stdin); // Reads input from user
log_message(user_input); // Passes user input safely to the function
return 0;
}
In the fixed code, using "%s"
as the format string ensures that printf
treats the user input as a string, preventing any possibility of format string attacks. This is a crucial practice to enhance the security of C applications that handle external input. Additionally, using sizeof(user_input)
enhances code safety by ensuring the buffer size is correctly utilized.