Home > Spring > CVE-2022-22965 SpringShell Vulnerability

CVE-2022-22965 SpringShell Vulnerability

SpringShell is a new Spring Framework Remote Code Execution (RCE), aka CVE-2022-22965, security vulnerability. Essentially all versions of the Spring Framework, including 5.3.0 to 5.3.17, 5.2.0 to 5.2.19, and older, unsupported versions are vulnerable.

Check if your Spring application is Vulnerable?

  • If you are using JDK 9 or higher.
  • If you are using Apache Tomcat as the Servlet container.
  • If your application build is packaged as a traditional WAR.
  • If you are using spring-webmvc or spring-webflux dependency.

Experts are saying even if you are not doing any of the above you may still be vulnerable. The Spring community admits, “the nature of the vulnerability is more general, and there may be other ways to exploit it.”

Vulnerability Fixes

Spring Framework 5.3.18 and 5.2.20 have already been released.

If you are using Spring Boot directly – upgrade to version 2.6.6

For maven users

<properties>
    <spring-framework.version>5.3.18</spring-framework.version>
</properties>

For gradle users

ext['spring-framework.version'] = '5.3.18'

If you want to handle it without upgrading, a fail-safe workaround by Spring official blog

Applications could extend RequestMappingHandlerAdapter to update the WebDataBinder at the end after all other initialization. In order to do that, a Spring Boot application can declare a WebMvcRegistrations bean (Spring MVC) or a WebFluxRegistrations bean (Spring WebFlux).

For Spring MVC(and similar in WebFlux):

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;
                }
            };
        }
    }
}