Update Log:
- 1 April 2022 9:00 CST - Update information on the Broadleaf Monolith 6.2 patch release
- 31 March 2022 13:00 CST - Initial update - sourced from https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement
https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities
This security alert is in response to CVE-2022-22965 - "Spring4Shell" in Spring Core that has been confirmed by several sources that leverage class injection (very severe),
Based on the information available from the Spring team, the following notes represent the known scenarios where this vulnerability can be exploited as well as ways to remediate it:
- JDK 9 or higher
- Apache Tomcat as the Servlet container
- Packaged as WAR
- spring-webmvc or spring-webflux dependency
Spring does caution that there may be other ways to exploit it that have not been reported yet.
Spring Framework versions 5.3.18 and 5.2.20 have been released which address this vulnerability.
Based on the information available, the following are actions that should be taken to secure Broadleaf Commerce Framework implementations:
Broadleaf Monolith Deployments
Broadleaf Monolith version 6.0 and older only support JDK 1.8 or less. Those versions of the framework should not be impacted so long as you are running JDK 1.8 or less.
Broadleaf Monolith version 6.1 is on Spring Framework version 5.1.x. If you are running the application as a Spring Boot executable jar, no mitigation is required. Clients that are running 6.1.x with Apache Tomcat, packaging using a WAR, and running JDK 9+ will require mitigation
Broadleaf Monolith version 6.2+ is on Spring Framework version 5.3.x. Broadleaf has released patches for all 6.2.x versions containing the upgrade to Spring Framework 5.3.18 and to Spring Boot 2.5.12 which contains the fix for the exploit. The recommendation for all 6.2.x clients is to apply the appropriate patch. Patch release versions are :
- 6.2.0.1-GA
- 6.2.1.5-GA
- 6.2.2.1-GA
Suggested Manual Mitigation Steps If Upgrading Spring Is Not Feasible
For 6.1.x implementations of Broadleaf Monolith that are impacted by this exploit a mitigation approach is required. Below are the steps suggested:
WebDataBinder Patch
One recommended patch is to `disallowedFields` on `WebDataBinder` through a @ControllerAdvice. This would be added to your site, admin, and API applications.
//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); } } //
This is the easiest approach but may leave holes in your application if your application has a controller that sets `disallowedFields` locally through its own `@InitBinder` method overriding the global ControllerAdvice. It is recommended to review your codebase for `disallowedFields` and verify that the global @ControllerAdvice would not be overridden.
Extending RequestMappingHandlerAdapter
A second recommendation is to extend the RequestMappingHandlerAdapter to update the WebDataBinder at the end after all other initialization. This approach is good if the global @ControllerAdvice will not work. In order to use this approach, a Spring Boot application can declare a WebMvcRegistrations bean (Spring MVC). Here is an example:
//code @SpringBootApplication @EnableAutoConfiguration public class SiteApplication extends SpringBootServletInitializer { @Configuration @EnableBroadleafSiteAutoConfiguration public static class BroadleafFrameworkConfiguration {} public static void main(String[] args) { SpringApplication.run(SiteApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(SiteApplication.class); } @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; } }; } } } //
Broadleaf Microservices Deployments
All of the Broadleaf Microservices are deployed using Spring Boot executable jars. This exploit does not impact this deployment approach. Nonetheless, our next patch release train (1.7.2-GA) will contain a Spring Framework upgrade to version 5.2.20 (from 5.2.19). Also, if desired, you can manually update the spring dependency version in your own pom. If your project pom inherits from spring boot parent pom, then you can declare a property in your pom to override the spring version:
<properties>
<spring-framework.version>5.2.20.RELEASE</spring-framework.version>
</properties>
Or, if you are consuming the microservices framework at versions 1.7+ and using the newer pom model, you may declare a dependency on the updated spring framework bom at an early point in the pom. The key point here is to declare prior to the broadleaf release train:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>5.2.20.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.broadleafcommerce.microservices</groupId> <artifactId>broadleaf-microservices-release-train</artifactId> <version>${blc.release.train}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>In either case, examine the build output of your project and confirm spring framework 5.2.20 versions are being resolved.