領先一步
VMware 提供訓練和認證,以加速您的進展。
瞭解更多更新
disallowedFields
解決方案中的小問題我想公告 Spring Framework 中的 RCE 漏洞,該漏洞在 CVE 發佈之前已洩露。此問題最初由 AntGroup FG 的 codeplutos、meizjm3i 在週二晚上深夜,格林威治標準時間午夜時分,回報給 VMware。週三,我們致力於調查、分析、找出修復方法、測試,同時目標是在週四緊急發佈。與此同時,同樣在週三,詳細資訊在網路上完整洩露,這就是為什麼我們要在發佈和 CVE 報告之前提供此更新。
此漏洞會影響在 JDK 9+ 上執行的 Spring MVC 和 Spring WebFlux 應用程式。特定的漏洞利用需要將應用程式打包並部署為 Servlet 容器上的傳統 WAR 檔。如果應用程式以 Spring Boot 可執行 jar 檔(即預設值)部署,則不會受到此漏洞的影響。但是,此漏洞的本質更為廣泛,可能還有其他利用它的方法。
以下是報告中特定情境的需求
spring-webmvc
或 spring-webflux
相依性。其他註記
ClassLoader
存取,並取決於實際使用的 Servlet 容器。已知 Tomcat 10.0.19、9.0.61、8.5.77 和更早版本容易受到攻擊。Payara 和 Glassfish 也已知容易受到攻擊。其他 Servlet 容器也可能容易受到攻擊。@ModelAttribute
註解或選擇性地不使用註解,且不使用任何其他 Spring Web 註解的控制器方法參數。@RequestBody
控制器方法參數(例如 JSON 反序列化)無關。但是,如果此類方法具有另一個透過資料綁定從查詢參數填充的方法參數,則它們仍然可能容易受到攻擊。建議的回應是更新至 Spring Framework 5.3.18 和 5.2.20 或更高版本。如果您已完成此操作,則無需任何解決方案。但是,有些人可能處於無法快速升級的情況。因此,我們在下面提供了一些解決方案。
請注意,解決方案不一定是互斥的,因為安全最好「深入」完成。
對於在 Tomcat 上執行且 Spring Framework 版本不受支援的舊版應用程式,升級至 Apache Tomcat 10.0.20、9.0.62 或 8.5.78 可提供足夠的保護。但是,這應視為一種戰術解決方案,主要目標應是盡快升級到目前受支援的 Spring Framework 版本。如果您採用這種方法,也應考慮設定禁止的欄位以進行深度防禦。
如果您既無法升級 Spring Framework 也無法升級 Apache Tomcat,則降級至 Java 8 是一種可行的解決方案。
另一個可行的解決方案是透過在全域設定 WebDataBinder
上的 disallowedFields
來停用與特定欄位的繫結
@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);
}
}
這通常有效,但作為集中應用的解決方案修復程式,可能會留下一些漏洞,特別是當控制器透過自己的 @InitBinder
方法在本機設定 disallowedFields
時,這會覆寫全域設定。
為了以更安全的方式應用解決方案,應用程式可以擴充 RequestMappingHandlerAdapter
以在所有其他初始化之後在最後更新 WebDataBinder
。為了做到這一點,Spring Boot 應用程式可以宣告 WebMvcRegistrations
Bean (Spring MVC) 或 WebFluxRegistrations
Bean (Spring WebFlux)。
例如在 Spring MVC 中 (WebFlux 中類似)
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;
}
};
}
}
}
對於沒有 Spring Boot 的 Spring MVC,應用程式可以從 @EnableWebMvc
切換為直接擴充 DelegatingWebMvcConfiguration
,如文件進階設定章節中所述,然後覆寫 createRequestMappingHandlerAdapter
方法。
有人猜測圍繞著棄用 SerializationUtils
的提交。此類別在框架內只有一種用法,並且不會暴露於外部輸入。棄用與此漏洞無關。
對於Spring Cloud Function 的 CVE 存在混淆,該 CVE 在此漏洞報告之前發佈。它也無關。