security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
今天有个接口打算使用矩阵变量来绑定参数,即使用@MatrixVariable注解来接收参数
调用接口后项目报了如下错误
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
完成的异常栈轨迹如下
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
at org.springframework.security.web.firewall.StrictHttpFirewall.rejectedBlacklistedUrls(StrictHttpFirewall.java:369) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:336) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108) ~[spring-boot-actuator-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119) ~[undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99) [undertow-servlet-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376) [undertow-core-2.0.28.Final.jar:2.0.28.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) [undertow-core-2.0.28.Final.jar:2.0.28.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_181]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181]
解决方法
前提,springmvc默认不能用矩阵变量,所以记得开启,springboot可以用如下方式开启
@Configuration
public class WebMvcAuthConfig implements WebMvcConfigurer { @Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper=new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
然后如果出现了标题的异常可以加入如下配置即可解决
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override
public void configure(WebSecurity web) throws Exception {
StrictHttpFirewall firewall = new StrictHttpFirewall();
//去掉";"黑名单
firewall.setAllowSemicolon(true);
//加入自定义的防火墙
web.httpFirewall(firewall);
super.configure(web);
}
}
闲的同学可以看下解决思路
解决思路
通过异常信息大概可以得知是因为url中带入了“;”符号所以请求地址非法,我们看下最近的报错的类StrictHttpFirewall 中369行的方法
private void rejectedBlacklistedUrls(HttpServletRequest request) {
for (String forbidden : this.encodedUrlBlacklist) {
//如果url中有黑名单的符号就报异常
if (encodedUrlContains(request, forbidden)) {
throw new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String \"" + forbidden + "\"");
}
}
for (String forbidden : this.decodedUrlBlacklist) {
if (decodedUrlContains(request, forbidden)) {
throw new RequestRejectedException("The request was rejected because the URL contained a potentially malicious String \"" + forbidden + "\"");
}
}
}
其中有个encodedUrlBlacklist就是所有的非法字符黑名单了,这儿会过滤所有非法字符,我们debug看下里面有哪些
果然第14个有";"符号,按理说springmvc既然有这个注解应该不至于自己定义为非法,查看该类的包名
package org.springframework.security.web.firewall
看包名也很明确了,项目因为使用了spring security有关的东西,这儿应该是spring security默认url不能带";"符号。有同学会想那我可不可以使用url编码躲开这个过滤? 当然了框架肯定是想到了这点儿,“;”进行url编码后为3b%,就是上图中第8个和第9个 (汗 连大小写都考虑到了 。。),所以我们肯定还是需要看到底那儿使用的这个类,能不能在项目初始化时将";"从黑名单中移除。
我们在StrictHttpFirewall中搜寻,看下哪些地方涉及到了";"符号 发现如下
public class StrictHttpFirewall implements HttpFirewall {
............ private static final List<String> FORBIDDEN_SEMICOLON = Collections.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));
............
public StrictHttpFirewall() {
urlBlacklistsAddAll(FORBIDDEN_SEMICOLON);
...
} private void urlBlacklistsAddAll(Collection<String> values) {
this.encodedUrlBlacklist.addAll(values);
this.decodedUrlBlacklist.addAll(values);
}
}
可以很明确的看到 该类在初始化的时候就将";" 添加到了encodedUrlBlacklist中,但是该类中还存在一个方法
public void setAllowSemicolon(boolean allowSemicolon) {
if (allowSemicolon) {
urlBlacklistsRemoveAll(FORBIDDEN_SEMICOLON);
} else {
urlBlacklistsAddAll(FORBIDDEN_SEMICOLON);
}
}
该方法目的相信已经相当明确了,调用该方法,就能将";"从黑名单中移除。那解决思路就应该有如下的步骤 ,找到使用该类的地方,然后找到创建对象的地方,调用这个移除黑名单方法将其移出黑名单。
那该如何找到调用的地方呢,其实异常轨迹中已经很明确了,截取前面几行和security有关的异常方法轨迹,
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
at org.springframework.security.web.firewall.StrictHttpFirewall.rejectedBlacklistedUrls(StrictHttpFirewall.java:369) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:336) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:194) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
通过这几行信息可以发现大概是security在执行过滤器的时候FilterChainProxy对象使用了StrictHttpFirewall类的过滤方法,那我们直接从FilterChainProxy最下面的那个doFilter方法开始看
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
if (clearContext) {
try {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
doFilterInternal(request, response, chain);
}
finally {
SecurityContextHolder.clearContext();
request.removeAttribute(FILTER_APPLIED);
}
}
else {
doFilterInternal(request, response, chain);
}
}
这儿没有找到和StrictHttpFirewall有关的信息,我们接着看下一个doFilterInternal方法
private void doFilterInternal(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//这儿会执行firewall(StrictHttpFirewall)里面的黑名单过滤方法
FirewalledRequest fwRequest = firewall
.getFirewalledRequest((HttpServletRequest) request);
HttpServletResponse fwResponse = firewall
.getFirewalledResponse((HttpServletResponse) response);
...............
}
这儿我们看到了和firewall有关的东西了,我们看下这个属性
private HttpFirewall firewall = new StrictHttpFirewall();
看来就是这个FilterChainProxy对象里默认声明了一个StrictHttpFirewall并执行了黑名单过滤方法,那我们需要修改的就是这个属性了,感觉已经成功了一半了。
那我们如何修改这个属性? 还是可以先看下类里面是否有赋值的方法,我们查看FilterChainProxy对象后发现有如下地方的代码可以自己设置firwall
public void setFirewall(HttpFirewall firewall) {
this.firewall = firewall;
}
看来FilterChainProxy中有自己设置HttpFirewall 地方,那我们现在的目的又变成了 找到FilterChainProxy初始化的地方,自己初始化一个StrictHttpFirewall对象并执行其setAllowSemicolon(true)方法,然后将这个firewall塞到FilterChainProxy中。
springsecutiry既然默认禁止 又提供了消除黑名单方法 ,那说明肯定有能配置的地方。我们使用idea全局搜索下,是否有地方使用了这个setFirewall方法,果然就搜索到了
看到这个相信大家就知道应该怎么办了,使用过spring secutiry的同学相信不会对WebSecurity这个类陌生。这个类保存spring security的一些核心配置。我们看下这个类中setFirewall片段
...........
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
if (httpFirewall != null) {
filterChainProxy.setFirewall(httpFirewall);
}
filterChainProxy.afterPropertiesSet(); .........
可以发现就是这儿判断是否有自定义的httpFirewall 如果有就传入自定义的,如果没有那就使用上面的FilterChainProxy对象初始化时的StrictHttpFirewall 。
private HttpFirewall httpFirewall;
public WebSecurity httpFirewall(HttpFirewall httpFirewall) {
this.httpFirewall = httpFirewall;
return this;
}
该类是没有初始化定义防火墙的,但是给了httpFirewall方法可以传入自定义的HttpFirewall 。所以我们到这儿就找到了最终的解决方案了,就是配置WebSecurity 。熟悉spring secutiry的同学都知道spring secutiry有专门的初始化抽象配置类WebSecurityConfigurerAdapter ,就像springmvc的WebMvcConfigurerAdapter一样。我们来看下WebSecurityConfigurerAdapter
果然在里面找到了可以配置webSecurity的方法 ,所以我们就直接继承这个类 然后重写这个方法
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override
public void configure(WebSecurity web) throws Exception {
StrictHttpFirewall firewall = new StrictHttpFirewall();
//去掉";"黑名单
firewall.setAllowSemicolon(true);
//加入自定义的防火墙
web.httpFirewall(firewall);
super.configure(web);
}
}
这个时候重启项目再调用接口 调用 localhost:8081/api/car/vehicle/test/8008208820;lon=23.203;lat=26.302
已经能够成功获取到了
security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"的更多相关文章
- The request was rejected because the URL contained a potentially malicious String ";"报错解决
报错信息 浏览器中看到的报错 错误摘要: The request was rejected because the URL contained a potentially malicious Stri ...
- SpringBoot整合升级Spring Security 报错 【The request was rejected because the URL was not normalized】
前言 最近LZ给项目框架升级, 从Spring1.x升级到Spring2.x, 在这里就不多赘述两个版本之间的区别以及升级的原因. 关于升级过程中踩的坑,在其他博文中会做比较详细的记录,以便给读者参考 ...
- spring boot The request was rejected because the URL was not normalized
升级spring boot 1.5.10.RELEASE 版本后,突然发现之前能Nginx代理能请求的地址抛如下异常: org.springframework.security.web.firewal ...
- FAIL - Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (112503036) exceeds the configured
Message: FAIL - Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.FileUpload ...
- 使用postman模拟上传文件到springMVC的坑:the request was rejected because no multipart boundary was found
参考该文解决问题:http://blog.csdn.net/sanjay_f/article/details/47407063 报错 threw exception [Request processi ...
- org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected be
1.错误描写叙述 八月 14, 2015 3:03:05 下午 com.opensymphony.xwork2.util.logging.jdk.JdkLogger warn 警告: Request ...
- Web开发-Servlet&HTTP&Request
<!doctype html>02 - JavaEE - Servlet&HTTP&Request figure:first-child { margin-top: -20 ...
- Atitit.面向接口的web 原理与设计重写 路由启动绑定配置url router rewriting urlpage mvc mvp的 java c#.net php js
Atitit.面向接口的web 原理与设计重写 路由启动绑定配置url router rewriting urlpage mvc mvp的 java c#.net php js 原理 通过vm带入启 ...
- [Security] Web Security Essentials
In this course, we'll learn how to exploit and then mitigate several common Web Security Vulnerabili ...
随机推荐
- Nearest Interesting Number
Polycarp knows that if the sum of the digits of a number is divisible by 33, then the number itself ...
- fileupload插件调用upload.parseRequest(request)解析得到空值问题
得到的list长度是0,项目配置不能改变,没办法了,只能将HttpServletRequest强换成DefaultMultipartHttpServletRequest ,直接获取表单中的字段了.方法 ...
- C/S编程
https://blog.csdn.net/antony1776/article/details/73717666 实现C/S程序,加上登录注册聊天等功能. 然后要做个协议的样子出来. 比如说注册功能 ...
- STM32程序烧录总结
1.程序烧录方式 1)ST-LINK下载 2)SWD下载 SWD对应的引脚为:GND.RST.SWDIO.SWDCLK SWD与Jlink的比较 3)串口下载 串口下载不能直接在MDK点击Downlo ...
- Nuxt配置动态路由以及参数校验
动态路由就是带参数的路由.比如我们商品列表里很多商品详细页,这时候就需要动态路由的帮助了. 比如我们新建一个commodity文件夹,新建一个index.vue 文件,然后新建一个_id.vue (以 ...
- 每天进步一点点------altium designer 实用的快捷键
1.设计浏览器快捷键: 鼠标左击 选择鼠标位置的文档鼠标双击 编辑鼠标位置的文档鼠标右击 ...
- yii2 gii开启
gii模块可以通过配置yii\base\Application::modules属性开启它.在config/web.php文件中会有以下配置代码: $config = [ ... ]; if (YII ...
- 移动APP漏洞自动化检测平台建设
移动APP漏洞自动化检测平台建设 前言:本文是<移动APP客户端安全笔记>系列原创文章中的第一篇,主要讲的是企业移动APP自动化漏洞检测平台建设,移动APP漏洞检测发展史与前沿技术,A ...
- jmeter实现SMTP邮件协议压测
实现目的 通过jmeter的SMTP取样器,调用SMTP协议,批量进行邮件的发送,已达到压测的目的. 脚本实现 User Defined Variables定义用户变量 编辑SMTP Sampler取 ...
- Linux按文件名搜索命令
find 搜索目录 -name 目标名字 find / -name file名 /代表是全盘搜索,也可以指定目录搜索 find 搜索文件的命令格式: find [搜索范围] [匹配条件] 选项: -n ...