The java.io package includes a PrintStream class that has two equivalent formatting methods format() and printf(). System.out is a PrintStream object, allowing PrintStream methods to be invoked on the standard output stream. The risks from using these methods are not as high as from using similar functions in C or C++ [Seacord 2013]. The standard library implementations throw an exception when any conversion argument fails to match the corresponding format specifier. Although this helps mitigate against exploits, if untrusted data is incorporated into a format string, it can result in an information leak or allow a denial-of-service attack. Consequently, unsanitized input from an untrusted source must never be incorporated into format strings.
This noncompliant code example leaks information about a users credit card. It incorporates untrusted data in a format string.
class Format {
static Calendar c = new GregorianCalendar(1995, GregorianCalendar.MAY, 23);
public static void main(String[] args) {
// args[0] should contain the credit card expiration date
// but might contain %1$tm, %1$te or %1$tY format specifiers
System.out.format(
args[0] + " did not match! HINT: It was issued on %1$terd of some month", c
);
}
}
|
In the absence of proper input validation, an attacker can determine the date against which the input is verified by supplying an input string that includes the %1$tm, %1$te, or %1$tY format specifiers. In this example, these format specifiers print 05 (May), 23 (day) and 1995 (year), respectively.
This compliant solution excludes untrusted user input from the format string. While arg[0] may still contain one or more format specifiers, these are now rendered inert.
class Format {
static Calendar c =
new GregorianCalendar(1995, GregorianCalendar.MAY, 23);
public static void main(String[] args) {
// args[0] is the credit card expiration date
// Perform comparison with c,
// if it doesn't match, print the following line
System.out.format(
"%s did not match! HINT: It was issued on %terd of some month",
args[0], c
);
}
}
|
Incorporating untrusted data in a format string may result in information leaks or allow a denial-of-service attack.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
IDS06-J | Medium | Unlikely | Medium | P4 | L3 |
Static analysis tools that perform taint analysis can diagnose some violations of this rule.
| CERT Perl Secure Coding Standard | IDS30-PL. Exclude user input from format strings |
Injection [RST] | |
CWE-134, Uncontrolled format string |
[API 2006] | |
Chapter 6, "Formatted Output" |