decorative image for blog on spring RCE vulnerability
March 31, 2022

Spring RCE 0-Day Vulnerability: What Users Need to Know About "Spring4Shell"

Security
Java

On March 30, 2022, researchers disclosed a major remote code execution (RCE) vulnerability in the Spring Core framework. Dubbed Spring4Shell by blog authors, developers in the field were able to develop a proof of concept in which exploitable code targets the zero-day vulnerability of the Spring Core module in Spring Framework.

In this blog, we look at how this exploit works, who it impacts, and the steps users need to take to patch or otherwise mitigate the Spring4Shell Spring RCE vulnerability.

How Does the "Spring4Shell" Spring RCE Vulnerability Work?

The detail of the exploit begins with requiring a DataBinder enabled endpoint and is heavily dependent on the servlet container for the application itself.

An example would be an instance of Tomcat with Spring deployed on it, with the WebAppClassLoader being accessible, this allows attackers to call getters and setters to write malicious JSP files to disk. This also depends on the user using JDK 9 or above. With one of the vulnerable JDK’s being used, the attacker is able to obtain AccessLogValve objects and manipulatable field values through the parameter binding function of Spring when certain conditions are met. This then triggers the pipeline mechanism and arbitrary writing fields. 

Who Is Impacted by "Spring4Shell"?

This vulnerability currently affects Spring Framework versions 5.3.0 through 5.3.17, 5.2.0 through 5.2.19, and all previous retired and unsupported versions as well. Full details around the vulnerability can be found at the CVE listing here.

Patches and Workarounds for "Spring4Shell"

If you are on an affected version, the solution to this issue is to upgrade to the latest versions of Spring Framework that contain a patch to this issue. However, as many of our customers know, upgrading isn’t always an option. At this time, there is a workaround for those who cannot quickly or safely perform an upgrade . 

How to Patch "Spring4Shell"

Patched versions of Spring Framework 5.3.18 and 5.2.20, as well as Spring Boot 2.5.12 and 2.6.6 are now available from the Spring engineering team here.

"Spring4Shell" Workarounds

To mitigate an unpatched version of Spring for this vulnerability the recommendation is to adjust disallowedFields on WebDataBinder through using an @CointrollerAdvice. Here’s an example:

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

}

Testing has shown this generally works but can still leave some loopholes in place. If a controller sets disallowedFields locally through hit’s own @InitBinder method, it will override the global settings.

A better way of applying this workaround is to have your application extend RequestMappingHandlerAdapter to update WebDataBinder at the end after all other initialization. To do this, your Spring Boot application must declare a WebMvcRegistrations bean (Spring MVC) or a WebFluxRegistrations bean (Spring WebFlux).

For example:

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

If you’re using Spring MVC without Spring Boot, an application might switch from @EnableWebMvc to extending DelegatingWebMvcConfiguration directly. With these workarounds in mind, OpenLogic advises users to upgrade if they are able to. 

Final Thoughts

To conclude, the Spring4Shell vulnerability affects previous versions of the 5.3.x and 5.2.x branches of Spring Framework. Mitigations detailed above exist, but are not as solid of a solution as upgrading to the latest patched version of Spring Framework -- which is the course of action OpenLogic suggests and recommends at this time.

Need Guidance or Support?

If you need help patching or mitigating the "Spring4Shell" vulnerability, or ensuring your Spring Framework or Spring Boot deployments are supported and secure, OpenLogic can help. Click the button below to speak with an expert today.

Talk to an Expert