Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
Maven

GHSA-mjmj-j48q-9wg2

HIGH

SnakeYaml Constructor Deserialization Remote Code Execution

Also known asCVE-2022-1471
Published
Dec 12, 2022
Updated
Jul 8, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
7 known

EPSS Exploitation Probability

via FIRST.org ↗
99.6%probability of exploitation in next 30 days
Very High Risk100th percentile-0.05%
92.1%94.7%97.4%100.0%93.8%99.6%Jan 26May 26Jul 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Blast Radius

1 pkg affected
org.yaml:snakeyaml

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Maven packages — download data is not available via public APIs for these ecosystems.

Description

Summary

SnakeYaml's Constructor class, which inherits from SafeConstructor, allows any type be deserialized given the following line:

new Yaml(new Constructor(TestDataClass.class)).load(yamlContent);

Types do not have to match the types of properties in the target class. A ConstructorException is thrown, but only after a malicious payload is deserialized.

Severity

High, lack of type checks during deserialization allows remote code execution.

Proof of Concept

Execute bash run.sh. The PoC uses Constructor to deserialize a payload for RCE. RCE is demonstrated by using a payload which performs a http request to http://127.0.0.1:8000.

Example output of successful run of proof of concept:

$ bash run.sh

[+] Downloading snakeyaml if needed
[+] Starting mock HTTP server on 127.0.0.1:8000 to demonstrate RCE
nc: no process found
[+] Compiling and running Proof of Concept, which a payload that sends a HTTP request to mock web server.
[+] An exception is expected.
Exception:
Cannot create property=payload for JavaBean=Main$TestDataClass@3cbbc1e0
 in 'string', line 1, column 1:
    payload: !!javax.script.ScriptEn ... 
    ^
Can not set java.lang.String field Main$TestDataClass.payload to javax.script.ScriptEngineManager
 in 'string', line 1, column 10:
    payload: !!javax.script.ScriptEngineManag ... 
             ^

	at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:291)
	at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:172)
	at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:332)
	at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:230)
	at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:220)
	at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:174)
	at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:158)
	at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:491)
	at org.yaml.snakeyaml.Yaml.load(Yaml.java:416)
	at Main.main(Main.java:37)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field Main$TestDataClass.payload to javax.script.ScriptEngineManager
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
	at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
	at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
	at java.base/java.lang.reflect.Field.set(Field.java:780)
	at org.yaml.snakeyaml.introspector.FieldProperty.set(FieldProperty.java:44)
	at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:286)
	... 9 more
[+] Dumping Received HTTP Request. Will not be empty if PoC worked
GET /proof-of-concept HTTP/1.1
User-Agent: Java/11.0.14
Host: localhost:8000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

Further Analysis

Potential mitigations include, leveraging SnakeYaml's SafeConstructor while parsing untrusted content.

See https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in#comment-64581479 for discussion on the subject.

Timeline

Date reported: 4/11/2022 Date fixed: 30/12/2022 Date disclosed: 10/13/2022

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
Mavenorg.yaml:snakeyamlall versions2.0
Exploits & PoCs
7

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for org.yaml:snakeyaml. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update org.yaml:snakeyaml to 2.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-mjmj-j48q-9wg2 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-mjmj-j48q-9wg2 is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-mjmj-j48q-9wg2. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary SnakeYaml's `Constructor` class, which inherits from `SafeConstructor`, allows any type be deserialized given the following line: new Yaml(new Constructor(TestDataClass.class)).load(yamlContent); Types do not have to match the types of properties in the target class. A `ConstructorException` is thrown, but only after a malicious payload is deserialized. ### Severity High, lack of type checks during deserialization allows remote code execution. ### Proof of Concept Execute `bash run.sh`. The PoC uses Constructor to deserialize a payload for RCE. RCE is demonstrated by using a pa
O3 Security · Impact-Aware SCA

Is GHSA-mjmj-j48q-9wg2 in your dependencies?

O3 detects GHSA-mjmj-j48q-9wg2 across Maven dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.