日志出现:
[http-nio-80-exec-3] ERROR o.a.c.c.C.[.[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String "%2e"
原因:
在我使用的 Spring Security 框架中提供了一个 HttpFirewall,这是一个请求防火墙,它可以自动处理掉一些非法请求,请求地址格式中不能包含;
、//
、 %
.......等字符或编码,必须是标准化 URL。
解决方法:
如果希望请求地址中可以出现 ;
或编码后的字符 %3b
或者 %3B
,可以按照如下方式配置:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowSemicolon(true);
return firewall;
}
// 设置完成上一步之后,再次访问相同的接口错误是 404 需要再配置SpringMVC 使 ; 不要被自动移除
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
如果你希望请求地址中可以出现 //
,可以按照如下方式配置:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedDoubleSlash(true);
return firewall;
}
如果希望请求地址中可以出现 %
,可以按照如下方式配置:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPercent(true);
return firewall;
}
如果希望请求地址中出现 /
编码后的字符 %2F
或者 %2f
,可以按照如下方式配置:
如果希望请求地址中出现 \
编码后的字符 %5C
或者 %5c
,可以按照如下方式配置:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowBackSlash(true);
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
如果希望请求地址中出现 .
或编码之后的字符 %2e
、%2E
,可以按照如下方式配置:
@Bean
HttpFirewall httpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedPeriod(true);
return firewall;
}
总结:
虽然我们可以手动修改 Spring Security 中的这些限制,但是不建议大家做修改,每一条限制都有它的原由,每放开一个限制,就会带来未知的安全风险。