Spring 官方修复零日漏洞,推出 Spring Boot 2.6.6、2.5.12 等新版本

x33g5p2x  于2022-05-23 转载在 Spring  
字(3.5k)|赞(0)|评价(0)|浏览(381)

一、漏洞说明

这个漏洞还要从 3 月 29 日晚间说起!

彼时有不少网友爆料,Spring 框架出现 “史诗级” RCE 漏洞,平地一声雷,一时之间,快要入睡的开发者们纷纷坐起查看关于漏洞的情况,闹得技术圈中人心惶惶。

不过有些不同寻常的是,这个漏洞并没有像 Log4j2 事件那样引起圈内诸多企业大厂的紧急行动,甚至连国外披露漏洞的根源也是来自 QQ 和国内部分网络安全网站。

Spring 官方证实:框架爆大漏洞,JDK 9 及以上版本均受影响

这也让不少网友猜测,该漏洞应该是国内某个安全机构、安全人员最先发现的。

果不其然,据 3 月 31 日国家信息安全漏洞共享平台(CNVD)发布的《关于 Spring 框架存在远程命令执行漏洞的安全公告》显示,这群神秘的白帽子们包括蚂蚁科技集团、奇安信科技、杭州安恒信息技术、安天科技、360、北京天融信,当然这些都是后话了。

1.1 Spring 零日漏洞真的存在

就在开发者越来越焦灼时,Spring.io 官方于 3 月 31 日晚间出面证实了这一漏洞的存在,并带来了解决方案。

Spring 官方证实:框架爆大漏洞,JDK 9 及以上版本均受影响

根据公告,我们发现这个漏洞的影响远比我们想象的更为严重,如果满足以下几种门槛,极有可能受漏洞影响:

JDK 9 或更高版本

Apache Tomcat 作为 Servlet 容器

打包为传统的 WAR(与 Spring Boot 可执行 jar 相比)

spring-webmvc 或 spring-webflux 依赖

Spring Framework 版本 5.3.0 到 5.3.17、5.2.0 到 5.2.19 以及更早的版本

二、官方更新

2.1 初步解决方案

当前 Spring.io 已经发布了 Spring Framework 5.3.18 和 5.2.20 版本,同时还带来了最新的依赖于 Spring Framework 5.3.18 的 Spring Boot 2.6.6 和 2.5.12 。因为如果你能升级到 Spring Framework 5.3.18 和 5.2.20,就不用以下的修复方案了。

如果不可以,Spring 官方建议通过 @ControllerAdvice 来设置 WebDataBinder 的 disallowedFields。

  1. @ControllerAdvice
  2. @Order(Ordered.LOWEST_PRECEDENCE)
  3. public class BinderControllerAdvice {
  4. @InitBinder
  5. public void setAllowedFields(WebDataBinder dataBinder) {
  6. String denylist = new String{"class.*", "Class.*", "*.class.*", "*.Class.*"};
  7. dataBinder.setDisallowedFields(denylist);
  8. }
  9. }

在 Spring MVC 中(在 WebFlux 中也类似)示例如下:

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.web.bind.ServletRequestDataBinder;
  6. import org.springframework.web.context.request.NativeWebRequest;
  7. import org.springframework.web.method.annotation.InitBinderDataBinderFactory;
  8. import org.springframework.web.method.support.InvocableHandlerMethod;
  9. import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
  10. import org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory;
  11. import java.util.ArrayList;
  12. import java.util.Arrays;
  13. import java.util.Collections;
  14. import java.util.List;
  15. @SpringBootApplication
  16. public class MyApp {
  17. public static void main(String[] args) {
  18. SpringApplication.run(MyApp.class, args);
  19. }
  20. @Bean
  21. public WebMvcRegistrations mvcRegistrations() {
  22. return new WebMvcRegistrations() {
  23. @Override
  24. public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
  25. return new ExtendedRequestMappingHandlerAdapter();
  26. }
  27. };
  28. }
  29. private static class ExtendedRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
  30. @Override
  31. protected InitBinderDataBinderFactory createDataBinderFactory(List<InvocableHandlerMethod> methods) {
  32. return new ServletRequestDataBinderFactory(methods, getWebBindingInitializer()) {
  33. @Override
  34. protected ServletRequestDataBinder createBinderInstance(Object target, String name, NativeWebRequest request) throws Exception {
  35. ServletRequestDataBinder binder = super.createBinderInstance(target, name, request);
  36. String[] fields = binder.getDisallowedFields();
  37. List<String> fieldList = new ArrayList<>(fields != null ? Arrays.asList(fields) : Collections.emptyList());
  38. fieldList.addAll(Arrays.asList("class.*", "Class.*", "*.class.*", "*.Class.*"));
  39. binder.setDisallowedFields(fieldList.toArray(new String[]{}));
  40. return binder;
  41. }
  42. };
  43. }
  44. }
  45. }

对于没有 Spring Boot 的 Spring MVC,应用程序可以从 @EnableWebMvc 切换到直接扩展
DelegatingWebMvcConfiguration,如这个文档中(https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-config-advanced-java)高级配置部分所述,然后重写 createRequestMappingHandlerAdapter 方法。

基于以上,我们建议受漏洞影响的产品(服务)厂商和信息系统运营者第一时间进行自查,并及时升级至最新版本。

相关文章