### SummarySnakeYaml's `Constructor` class, which inherits from `SafeConstructor`, allowsany 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 thetarget class. A `ConstructorException` is thrown, but only after a maliciouspayload is deserialized.### SeverityHigh, lack of type checks during deserialization allows remote code execution.### Proof of ConceptExecute `bash run.sh`. The PoC uses Constructor to deserialize a payloadfor RCE. RCE is demonstrated by using a payload which performs a http request tohttp://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 RCEnc: 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 workedGET /proof-of-concept HTTP/1.1User-Agent: Java/11.0.14Host: localhost:8000Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2Connection: keep-alive```### Further AnalysisPotential 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](https://bitbucket.org/snakeyaml/snakeyaml/pull-requests/44)**Date disclosed**: 10/13/2022
Fix available through Seal Security. No upgrade required, protect your application instantly.
Fix without upgrading