Information Security 6 min read

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.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
How to Mitigate the Unpublished Spring Framework RCE Vulnerability in JDK 9+ Environments

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

@EnableWebMvc

and delegating to

DelegatingWebMvcConfiguration

, then override the

createRequestMappingHandlerAdapter

method.

References

[1] Advanced configuration: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-advanced-java

JavasecurityPatchTomcatRCESpring MVCSpring Framework
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.