ControllerAdvice @InitBinder setDisallowedFields 不起作用
ControllerAdvice @InitBinder setDisallowedFields doesn't work
已使用 spring 引导版本 2.5.3 构建了一个 JAVA 项目。
由于存在“Spring4shell”(CVE-2022-22965) 安全风险,我们必须采取缓解措施。
无法升级 Spring 引导版本,因为其他几个依赖项与最新的 Spring 引导版本不兼容。
因此,已决定根据 https://www.springcloud.io/post/2022-03/spring-framework-rce-early-announcement/#gsc.tab=0
应用建议的解决方法
根据指南,建议了 2 个解决方法。
- 通过 @ControllerAdvice 方法在 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);
}
}
- 扩展 RequestMappingHandlerAdapter 以更新 WebDataBinder:
@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;
}
};
}
}
两种方法都已尝试,但其中 none 可能会拒绝以下请求。
HOST:PORT/path?class.module.classLoader.URLs%5B0%5D=0
我们方法的缺失点是什么?
将值设置为 webDataBinder.setDisallowedFields() 不会拒绝请求。
WebDataBinder 提供了setAllowedFields 和setDisallowedFields 两种方法来设置模型对象数据绑定过程中可以和不可以使用的属性名列表。
此验证将在 org.springframework.validation.DataBinder::doBind 方法中进行。在 doBind 方法中不允许的字段将从字段列表中删除
已使用 spring 引导版本 2.5.3 构建了一个 JAVA 项目。
由于存在“Spring4shell”(CVE-2022-22965) 安全风险,我们必须采取缓解措施。
无法升级 Spring 引导版本,因为其他几个依赖项与最新的 Spring 引导版本不兼容。 因此,已决定根据 https://www.springcloud.io/post/2022-03/spring-framework-rce-early-announcement/#gsc.tab=0
应用建议的解决方法根据指南,建议了 2 个解决方法。
- 通过 @ControllerAdvice 方法在 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);
}
}
- 扩展 RequestMappingHandlerAdapter 以更新 WebDataBinder:
@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;
}
};
}
}
两种方法都已尝试,但其中 none 可能会拒绝以下请求。
HOST:PORT/path?class.module.classLoader.URLs%5B0%5D=0
我们方法的缺失点是什么?
将值设置为 webDataBinder.setDisallowedFields() 不会拒绝请求。
WebDataBinder 提供了setAllowedFields 和setDisallowedFields 两种方法来设置模型对象数据绑定过程中可以和不可以使用的属性名列表。 此验证将在 org.springframework.validation.DataBinder::doBind 方法中进行。在 doBind 方法中不允许的字段将从字段列表中删除