Spring 淪陷了!這樣的標題這幾天是不是看膩了?然而,仔細看看都是拿著之前的幾個毫不相干的CVE來大吹特吹。所以,昨天發了一篇關於最近的文章,聊了聊這些讓人迷惑的行銷文、以及提醒大家不要去下載一些利用漏洞提供修補程式的釣魚內容。而對於這個網傳的漏洞,依然保持關注狀態,因為確實可能存在,只是沒有官宣。
就在不久前(3月31日晚),Spring 社群釋出了一篇名為《》的文章,官宣了最近網傳的Spring漏洞。這也證實了網傳漏洞確實存在,並且並非最近很多文章說提到的3月28、29日公佈的CVE,如果你是照著那些文章解決問題的話,請根據這次官宣內容重新來過吧。
這次確定的Spring核心框架中的RCE漏洞,CVE號為CVE-2022-22965
[1]。
這個漏洞是在週二深夜,由AntGroup FG的codePlutos,meizjm3i向VMware報告。週三,Spring官方對該問題進行了調查、分析並確定瞭解決方案,同時計劃在週四進行緊急版本的釋出。
由於該漏洞被洩漏在網路上,所以Spring官方緊急釋出了相關修復的版本,因為是Spring核心框架中的漏洞,所以涉及面較廣。所以在這篇博文中也是在不斷的持續更新進展,下面截止到本文發稿的進展時間線:
下面就來一起看看這個被網傳了2天的神祕漏洞的官宣內容和解決方案。
影響範圍
該漏洞的利用需要滿足下面的條件:
- JDK 9 +
- 使用Apache Tomcat部署
- 使用WAR方式打包
- 依賴spring-webmvc或spring-webflux
雖然可能國內大部分使用者還在用JDK 8、或者採用內建Tomcat的方式執行,但由於該漏洞的特性比較普遍,不排除其他利用方式的存在。所以,DD還是建議在有條件的情況下,儘快升到最新版本來避免可能存在的風險發生。
解決方案
因為這次不是網傳,而是 Spring 官宣,所以解決方案已經相對完善和容易了,受影響的使用者可以通過下面的方法解決該漏洞的風險:
- Spring 5.3.x使用者升級到5.3.18+
- Spring 5.2.x使用者升級到5.2.20+
- Spring Boot 2.6.x使用者升級到2.6.6+
- Spring Boot 2.5.x使用者升級到2.5.12+
對於該漏洞的複習及更多細節,這裡因為篇幅有限,就不具體介紹了。
然後,這裡需要特別再提一下,之前已經收到訊息並有所行動的小夥伴,沒猜錯的話應該都是用下面的解決方案來處理的吧?
@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); } } |
這次 Spring 官方推文裡,證實了該方法是有效的,但可能會留下一些其他隱患,特別是當Controller
通過其自己的@InitBinder
方法在本地設定disalloedFields
時,該方法會覆蓋全域性設定。
為了以更安全的方式應用解決方案,應用程式可以擴充套件RequestMappingHandlerAdapter
,以便在所有其他初始化結束後更新WebDataBinder
。官方給出了更好的解決方案,比如下面這樣:
@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; } }; } } } |
對於不是 Spring Boot 應用下的 Spring MVC 使用者,可以直接從@EnableWebMvc
切換到擴充套件DelegatingWebMvcConfiguration
,如檔案的高階設定部分所述[3],然後重寫createRequestMappingHandlerAdapter
方法來實現。
參考資料
- [1]
- [2]
- [3]