安全通告
Spring 框架 RCE 漏洞安全風(fēng)險通告
發(fā)布日期:2022-3-31
漏洞描述
近日,監(jiān)測到Spring框架曝出RCE漏洞。經(jīng)研究,已經(jīng)證實由于SerializationUtils#deserialize 基于 Java 的序列化機制,可導(dǎo)致遠程代碼執(zhí)行 (RCE),使用 JDK9 及以上版本皆有可能受到影響。
Spring是一個開放源代碼的設(shè)計層面框架,是為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的。它解決的是業(yè)務(wù)邏輯層和其他各層的松耦合問題,因此它將面向接口的編程思想貫穿整個系統(tǒng)應(yīng)用。當(dāng)用到Spring的參數(shù)綁定功能,同時Spring core運行在jre/jdk/openjdk 9以上的版本時,class新增了getModlue()方法,可以通過其來獲取classLoader,從而繞過現(xiàn)有的spring的java.lang.class.classLoader 黑名單防御機制,達到調(diào)用 classLoader 的目的,配合不同的 Loader 的 setter、getter 方法,達到命令執(zhí)行或任意文件讀寫等一系列效果。
考慮到 Spring 框架的廣泛應(yīng)用,漏洞利用整個過程操作簡單,該漏洞可能已被遠程攻擊者利用。建議相關(guān)用戶及時開展安全自查,做好相關(guān)防護措施,避免被外部攻擊者入侵。
漏洞危害
未經(jīng)授權(quán)的遠程攻擊者可以利用該漏洞達到命令執(zhí)行或任意文件讀寫等一系列效果。
漏洞等級
高危
漏洞利用條件
- JDK/JRE/OpenJDK 版本: 9 及以上;
- 使用了 Spring-beans 包;
- 使用了 Spring 參數(shù)綁定;
- Spring 參數(shù)綁定使用的是非基本參數(shù)類型,例如一般的 POJO 即可;
注:不是 java+Spring 就一定存在漏洞,還要根據(jù)具體業(yè)務(wù)代碼來進一步判斷。
自查措施
JDK版本號排查
在業(yè)務(wù)系統(tǒng)的運行服務(wù)器上,執(zhí)行“java -version”命令查看運行的JDK版本,如果版本號小于等于8,則不受漏洞影響。
Spring框架使用情況排查
一、如果業(yè)務(wù)系統(tǒng)項目以war包形式部署,按照如下步驟進行判斷:
- 解壓war包:將war文件的后綴修改成.zip ,解壓zip文件;
- 在解壓縮目錄下搜索是否存在 spring-beans-*.jar 格式的jar文件(例如spring-beans-5.3.16.jar),如存在則說明業(yè)務(wù)系統(tǒng)使用了spring框架進行開發(fā);
- 如果spring-beans-*.jar 文件不存在,則在解壓縮目錄下搜索class 文件是否存在,如存在則說明業(yè)務(wù)系統(tǒng)使用了Spring框架開發(fā)。
二、如果業(yè)務(wù)系統(tǒng)項目以jar包形式直接獨立運行,按照如下步驟進行判斷:
- 解壓jar包:將jar文件的后綴修改成.zip,解壓zip文件;
- 在解壓縮目錄下搜索是否存在spring-beans-*.jar 格式的jar文件(例如spring-beans-5.3.16.jar),如存在則說明業(yè)務(wù)系統(tǒng)使用了spring框架進行開發(fā);
- 如果spring-beans-*.jar 文件不存在,則在解壓縮目錄下搜索class 文件是否存在,如存在則說明業(yè)務(wù)系統(tǒng)使用了spring框架進行開發(fā)。
修復(fù)建議
官方暫時還未進行任何更新,臨時建議:
- 在應(yīng)用組全局搜索@InitBinder 注解,看看方法體內(nèi)是否調(diào)用dataBinder.setDisallowedFields 方法,如果發(fā)現(xiàn)此代碼片段的引入,則在原來的黑名單中添加{“class.*”,”Class.*”,”*.class.*”,”*.Class.*”}。(注:如果此代碼片段使用較多,則需要每個地方都追加)
- 在應(yīng)用系統(tǒng)的項目包下新建以下全局類,并保證這個類被 Spring 加載到(推薦在Controller 所在的包中添加)。完成類添加后,需對項目進行重新編譯打包和功能驗證測試,并重新發(fā)布項目。
import org.springframework.core.annotation.Order
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
@ControllerAdvice
@Order(10000)
public class GlobalControllerAdvice {
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
String[] abd = new String[]{“class.*”, “Class.*”, “*.class.*”, “*.Class.*”}
dataBinder.setDisallowedFields(abd);
}
}