There are two high-threat things you can do with format string vulnerabilities in C - leak data and overwrite memory - and neither are relevant in Java. Java's string formatter doesn't even have the "conversion" that is used for overwriting memory, as you noticed. However, Java also is generally safe against such attacks because Java - unlike C - actually checks the number of variadic parameters expected against the number present. If you request a parameter that isn't present - either by index or just by having too many conversions - the formatter will throw an exception. So, there's no way to run off the end of the parameter list and start reading other information from the stack (which is generally not intended to be user-viewable, and may reveal secrets ranging from ASLR masks to cryptographic keys, which could be useful if an attacker can control the format string and invoke the function multiple times).

Interestingly, Java doesn't object if you pass too many variadic parameters - only too few - so you can potentially reveal things that are not normally revealed if the function call is written with excess parameters that aren't usually used. However, that's a pretty unlikely kind of bug, and even then, you could only reveal what those parameters are.

Java's conversions are also type-safe. For example, in C, you can expose pointer values (very valuable when trying to write memory exploits, especially since this can also reveal things like ASLR masks) by asking a format string function to render a pointer (such as to a string) as a numeric type. In Java, that doesn't work; if you pass a string (or any other reference type) and somebody messes with the format string to ask for a hex number, it'll just cause an exception again.

It's worth noting that there is ONE kind of vulnerability possible here: denial of service. An attacker who controls the format string can easily cause the app to throw an exception, for example by supplying the illegal format conversion %0$d (which requests the "zeroeth" parameter as an integer type, when such indices must start at 1). This exception, if uncaught, will cause a crash (even if caught, it may prevent the app from completing its operation correctly). However, as far as I can tell, such denial-of-service risk is the only realistic threat from user-controlled format strings in Java.

Answer from CBHacking on Stack Exchange
Top answer
1 of 2
3

There are two high-threat things you can do with format string vulnerabilities in C - leak data and overwrite memory - and neither are relevant in Java. Java's string formatter doesn't even have the "conversion" that is used for overwriting memory, as you noticed. However, Java also is generally safe against such attacks because Java - unlike C - actually checks the number of variadic parameters expected against the number present. If you request a parameter that isn't present - either by index or just by having too many conversions - the formatter will throw an exception. So, there's no way to run off the end of the parameter list and start reading other information from the stack (which is generally not intended to be user-viewable, and may reveal secrets ranging from ASLR masks to cryptographic keys, which could be useful if an attacker can control the format string and invoke the function multiple times).

Interestingly, Java doesn't object if you pass too many variadic parameters - only too few - so you can potentially reveal things that are not normally revealed if the function call is written with excess parameters that aren't usually used. However, that's a pretty unlikely kind of bug, and even then, you could only reveal what those parameters are.

Java's conversions are also type-safe. For example, in C, you can expose pointer values (very valuable when trying to write memory exploits, especially since this can also reveal things like ASLR masks) by asking a format string function to render a pointer (such as to a string) as a numeric type. In Java, that doesn't work; if you pass a string (or any other reference type) and somebody messes with the format string to ask for a hex number, it'll just cause an exception again.

It's worth noting that there is ONE kind of vulnerability possible here: denial of service. An attacker who controls the format string can easily cause the app to throw an exception, for example by supplying the illegal format conversion %0$d (which requests the "zeroeth" parameter as an integer type, when such indices must start at 1). This exception, if uncaught, will cause a crash (even if caught, it may prevent the app from completing its operation correctly). However, as far as I can tell, such denial-of-service risk is the only realistic threat from user-controlled format strings in Java.

2 of 2
2

There are multiple potential vulnerabilities with this:

  • Log injection / log forging
    Depending on how you use the formatted message afterwards, it might be possible to perform log injection, for example to deceive the person reading the log files. However, this is also possible to some extent when the user input is only used as formatting argument.
  • Leaking arguments
    If additional arguments are provided to the format call which are not or only partially included in the formatted message by default, then a user-provided format string could expose these unused arguments.
    While some advisories mention this vulnerability, personally I think this is rather unlikely because the arguments to be leaked already have to part of the formatting call, e.g. String.format(userFormatStr, arg1, secretArg).
  • Denial of service: Runtime exception
    A user-controlled malformed format string could cause runtime exceptions such as a IllegalFormatException. Depending on how your application handles this, it might allow performing a denial of service attack.
  • Denial of service: Memory consumption
    The width of a format specifier can be misused to allocate large amounts of memory. This also works for the specifier %% (e.g. %10000%), so this can be performed regardless of which format arguments are provided.

More information:

  • Fortify: Denial of Service: Format String
  • SEI CERT Oracle Coding Standard for Java: IDS06-J. Exclude unsanitized user input from format strings
  • Tweet by Wouter Coekaerts about width denial of service
🌐
OWASP Foundation
owasp.org › www-project-web-security-testing-guide › v41 › 4-Web_Application_Security_Testing › 07-Input_Validation_Testing › 13.3-Testing_for_Format_String
Testing for format string vulnerability
In the Java example, a username containing any specifier that needs an input (including %x or %s) would cause the program to crash with IllegalFormatException. Although the examples are still subject to other problems, the vulnerability can ...
🌐
Medium
medium.com › @jhjaksimsam2 › what-is-format-string-attack-how-to-prevent-this-attack-59b480ce9989
What is Format String attack? How to prevent this attack. | by JDK | Medium
June 21, 2019 - Format String Attack generates an error when a developer accidentally write a printf() code without a variable, And hacker can use this error to steal the root. If there is no format string factor after last entered format string, in terms of ...
🌐
OWASP Foundation
owasp.org › www-project-web-security-testing-guide › latest › 4-Web_Application_Security_Testing › 07-Input_Validation_Testing › 13-Testing_for_Format_String_Injection
Testing for Format String Injection
In the Java example, a username containing any specifier that needs an input (including %x or %s) would cause the program to crash with IllegalFormatException. Although the examples are still subject to other problems, the vulnerability can ...
🌐
Hacking Lab
hackinglab.cz › en › blog › format-string-vulnerability
Format String Vulnerability - Hacking Lab
October 21, 2024 - Java responds to incorrect format parameters with an exception. If exceptions are not handled correctly, attackers can use them to launch DoS attacks [8]. If the Ruby language receives a format parameter it does · not know (e.g. %z), or if the function contains more format · parameters than arguments, the program execution is terminated ... Although the format string vulnerability is over twenty years old, it is still found in dozens every year in real systems (see CVE).
🌐
MITRE
cwe.mitre.org › data › definitions › 134.html
CWE - CWE-134: Use of Externally-Controlled Format String (4.20)
A community-developed list of SW & HW weaknesses that can become vulnerabilities
🌐
CodeQL
codeql.github.com › codeql-query-help › java › java-tainted-format-string
Use of externally-controlled format string — CodeQL query help documentation
If the format string contains ... library implementation for the format methods throws an exception if either the format specifier does not match the type of the argument, or if there are too few or too many arguments....
Find elsewhere
🌐
Eyal Itkin
eyalitkin.wordpress.com › 2017 › 05 › 24 › format-strings-behind-the-scenes
Format Strings – Behind the Scenes - Eyal Itkin - WordPress.com
May 24, 2017 - High level languages: Java and C#, and interpreter-based languages: python, php, perl, and ruby, are often treated as “immune” to such attacks. Mainly because the 2nd condition now doesn’t apply: these languages know how many arguments were passed to the format function, and they can even check their types for correctness. Nevertheless, over the years there were several reports about format string implementation vulnerabilities, such as CVE 2008-2664 (CRuby) and CVE 2005-3962 (Perl).
🌐
Dr. Dobb's
drdobbs.com › security › programming-language-format-string-vulne › 197002914
Programming Language Format String Vulnerabilities | Dr Dobb's
February 2, 2007 - But format string vulnerabilities are not limited to programs written in C and C++. Other languages that include format strings include Perl, PHP, Java, Python, and Ruby.
🌐
SEI
resources.sei.cmu.edu › library › asset-view.cfm
Programming Language Format String Vulnerabilities | CMU Software Engineering Institute
In this article, Hal Burch and Robert Seacord explore the potential consequences of format string vulnerabilities in Perl, PHP, Java, Python, and Ruby programs.
Top answer
1 of 1
2

There is no difference between the two snippets. Neither protects against 'string injection'.

There are only 4 non-boneheaded mitigations against string injection attacks:

  1. Ensure that where-ever the strings end up, it is impossible for this to be a security issue in any way or form. For example, if your data is going to a binary file where all system operators are aware the contents are straight from the web, it doesn't matter what's uploaded.

  2. Do not render the string at all. Throwing the baby out with the bathwater.

  3. Use a whitelist. If the string consists solely of these allowed things, allow it. By default, do not allow it.

  4. Use escapers.

  5. Honourable mention for the concept of blacklisting: Have a list of known-malicious stuff, and allow all strings unless they contain something on the blacklist. This is bone headed and should never be used. For example, if you scan incoming data for <script>, you messed up. Don't do this. It doesn't work. Blacklists are trivially bypassed. Whitelists are what you're looking for.

The vastly most common strategy is the 4th: Escapers. For example, when you have a web server that takes in a username and a user's telephone number and a user's full name, and then renders all this information back out on their public website, then:

  • The phone number should be mitigated using the whitelist strategy. A single +, digits in the range 0-9, spaces, dashes, and nothing else. If that's what the input is like, allow it. Otherwise don't.

  • The user's real name should be mitigated with escaping: Take the data as provided and inject it verbatim into your database, but treat this data as tainted in all interactions with that data: For example, when rendering that public page, the 'full name' string needs to be washed through an HTML escaper which e.g. replaces all < with &lt;.

Your code doesn't do any of these 4 things (either version of it).

In general it is an extremely bad idea to consider the string returned by an exception's .getMessage() to be already 'safe' (escaped / passed the whitelist verifier). Instead, the code that invokes .getMessage() needs to apply one of the 4 mitigations as explained above.

🌐
Beagle Security
beaglesecurity.com › blog › vulnerability › format-string-vulnerability.html
Format String Vulnerability
October 20, 2023 - Through this vulnerability, the attacker might run commands to extract information about the server, view the source code of the application. The attacker can crash the application by executing malicious code to create a segmentation fault and ...
🌐
CTF Handbook
ctf101.org › binary-exploitation › what-is-a-format-string-vulnerability
Format String Vulnerability - CTF Handbook
For example, if we can make the format argument "%x.%x.%x.%x", printf will pop off four stack values and print them in hexadecimal, potentially leaking sensitive information. printf can also index to an arbitrary "argument" with the following syntax: "%n$x" (where n is the decimal index of the argument you want). While these bugs are powerful, they're very rare nowadays, as all modern compilers warn when printf is called with a non-constant string.
🌐
OWASP Foundation
owasp.org › www-community › attacks › Format_string_attack
Format string attack | OWASP Foundation
The printf in the first line will not interpret the “%s%s%s%s%s%s” in the input string, and the output will be: “Hello World %s%s%s%s%s%s” · The line printf(argv[1]); in the example is vulnerable, if you compile the program and run it:
🌐
Infosec Institute
infosecinstitute.com › resources › secure-coding › how-to-exploit-format-string-vulnerabilities
How to exploit format string vulnerabilities | Infosec
September 21, 2020 - Format String vulnerabilities clearly can create great damage, when exploited. One can easily read data from arbitrary memory locations and even crash the applications using them. The impact can be more if these vulnerabilities are chained with other vulnerabilities such as buffer overflow.
🌐
Infosec Institute
resources.infosecinstitute.com › topic › how-to-exploit-format-string-vulnerabilities
How to exploit format string vulnerabilities - Infosec Resources
September 21, 2020 - Format String vulnerabilities clearly can create great damage, when exploited. One can easily read data from arbitrary memory locations and even crash the applications using them. The impact can be more if these vulnerabilities are chained with other vulnerabilities such as buffer overflow.
🌐
Medium
infosecwriteups.com › exploiting-format-string-vulnerability-97e3d588da1b
EXPLOITING FORMAT STRING VULNERABILITY | by AidenPearce369 | InfoSec Write-ups
January 18, 2024 - When the format string does not have a corresponding variable to call the data, it will start popping random values from stack irrespective of their location/address · Lets consider a simple program to test this vulnerability