Format string injection¶
Formatting functions interpret their format argument as instructions for consuming additional arguments. If untrusted text becomes that template, format directives may read unintended memory, crash the process, or, for some APIs and directives, write to memory. The impact is API- and language-dependent; a managed-language formatting error does not imply C-style memory corruption.
Trust boundary: a user's message is data to display, not a formatting program. SEI CERT FIO30-C recommends keeping untrusted input out of format strings.
C and C++: unsafe and safer examples¶
Both fragments assume message points to a valid, NUL-terminated string. Include <stdio.h> for C, or use the corresponding C++ API.
/* Unsafe: message controls the format template. */
printf(message);
/* Safer: the constant template expects one string argument. */
printf("%s", message);
For binary data or text without a guaranteed terminator, use a length-aware operation such as fwrite(data, 1, length, stdout) after validating the buffer and length. printf("%s", ...) does not make an invalid pointer or an unterminated buffer safe. Check output errors where delivery matters.
Objective-C: keep the format constant¶
With Foundation, treat a caller-provided NSString as the object argument:
// Unsafe
NSLog(userMessage);
// Safer formatting; the message may still be inappropriate to log.
NSLog(@"%@", userMessage);
Constant formatting fixes the interpretation boundary. It does not redact credentials or prevent raw control characters from disrupting a log viewer. Prefer structured, allowlisted events for sensitive workflows; see sensitive logging.
Regression test¶
In a local test, capture the safer function's output for ordinary text and text containing a literal percent sign, such as Progress: 50%. Confirm it is preserved as data. Do not run the unsafe variant with undefined argument consumption. Enable compiler format warnings such as -Wformat and -Wformat-security when supported, and review calls where the format is not a literal.
Related: memory safety and the separate .NET composite formatting rule.
Reference: CWE-134 — use of an externally controlled format string.