How to Mitigate the Unpublished Spring Framework RCE Vulnerability in JDK 9+ Environments
This article explains the newly disclosed Spring Framework remote code execution flaw affecting JDK 9+ Spring MVC/WebFlux applications deployed as WARs on Apache Tomcat, outlines the affected conditions, current patch status, and provides code‑level workarounds for safe remediation.
1. Overview
Spring Framework confirmed an RCE vulnerability that had not yet been assigned a CVE. It was first reported to VMware on Tuesday night, investigated, fixed, tested, and scheduled for an emergency release on Thursday. The vulnerability was leaked online on Wednesday, after which Spring published a CVE.
2. About this RCE
The flaw affects Spring MVC and Spring WebFlux applications running on JDK 9+ when packaged as a WAR and deployed to Apache Tomcat. It does not affect embedded Tomcat in Spring Boot, though the vulnerability may be exploitable by other means.
3. Are you affected?
The report specifies the following requirements:
JDK 9 or higher
Apache Tomcat as the servlet container
Packaged as a WAR
However, the vulnerability’s nature is broader and other, unreported exploitation methods may exist.
4. Status
Spring Framework 5.3.18 and 5.2.20 have been released. Corresponding Spring Boot versions are in progress and expected within the next hour.
5. Fixes
Note: Spring Framework versions 5.3.18 and 5.2.20 address the issue and are available on Maven Central. If you can upgrade, no further workaround is needed.
The leaked report suggests the following configuration:
<code>@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public class BinderControllerAdvice {
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};
dataBinder.setDisallowedFields(denylist);
}
}
</code>This usually works, but as a global fix it may leave gaps if controllers set their own bindings locally.
For a safer approach, the application can extend after all other initializations. In Spring Boot, declare a bean for Spring MVC or Spring WebFlux.
Example for Spring MVC (similar for WebFlux):
<code>package car.app;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.InitBinderDataBinderFactory;
import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory;
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(CarApp.class, args);
}
@Bean
public WebMvcRegistrations mvcRegistrations() {
return new WebMvcRegistrations() {
@Override
public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
return new ExtendedRequestMappingHandlerAdapter();
}
};
}
private static class ExtendedRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
@Override
protected InitBinderDataBinderFactory createDataBinderFactory(List<InvocableHandlerMethod> methods) {
return new ServletRequestDataBinderFactory(methods, getWebBindingInitializer()) {
@Override
protected ServletRequestDataBinder createBinderInstance(
Object target, String name, NativeWebRequest request) throws Exception {
ServletRequestDataBinder binder = super.createBinderInstance(target, name, request);
String[] fields = binder.getDisallowedFields();
List<String> fieldList = new ArrayList<>(fields != null ? Arrays.asList(fields) : Collections.emptyList());
fieldList.addAll(Arrays.asList("class.*", "Class.*", "*.class.*", "*.Class.*"));
binder.setDisallowedFields(fieldList.toArray(new String[] {}));
return binder;
}
};
}
}
}
</code>For Spring MVC applications without Spring Boot, you can switch to the extended configuration using
@EnableWebMvcand delegating to
DelegatingWebMvcConfiguration, then override the
createRequestMappingHandlerAdaptermethod.
References
[1] Advanced configuration: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-advanced-java
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.