今天有个接口打算使用矩阵变量来绑定参数,即使用@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 ";"的更多相关文章

  1. The request was rejected because the URL contained a potentially malicious String ";"报错解决

    报错信息 浏览器中看到的报错 错误摘要: The request was rejected because the URL contained a potentially malicious Stri ...

  2. SpringBoot整合升级Spring Security 报错 【The request was rejected because the URL was not normalized】

    前言 最近LZ给项目框架升级, 从Spring1.x升级到Spring2.x, 在这里就不多赘述两个版本之间的区别以及升级的原因. 关于升级过程中踩的坑,在其他博文中会做比较详细的记录,以便给读者参考 ...

  3. spring boot The request was rejected because the URL was not normalized

    升级spring boot 1.5.10.RELEASE 版本后,突然发现之前能Nginx代理能请求的地址抛如下异常: org.springframework.security.web.firewal ...

  4. 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 ...

  5. 使用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 ...

  6. 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 ...

  7. Web开发-Servlet&HTTP&Request

    <!doctype html>02 - JavaEE - Servlet&HTTP&Request figure:first-child { margin-top: -20 ...

  8. 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带入启 ...

  9. [Security] Web Security Essentials

    In this course, we'll learn how to exploit and then mitigate several common Web Security Vulnerabili ...

随机推荐

  1. Nearest Interesting Number

    Polycarp knows that if the sum of the digits of a number is divisible by 33, then the number itself ...

  2. fileupload插件调用upload.parseRequest(request)解析得到空值问题

    得到的list长度是0,项目配置不能改变,没办法了,只能将HttpServletRequest强换成DefaultMultipartHttpServletRequest ,直接获取表单中的字段了.方法 ...

  3. C/S编程

    https://blog.csdn.net/antony1776/article/details/73717666 实现C/S程序,加上登录注册聊天等功能. 然后要做个协议的样子出来. 比如说注册功能 ...

  4. STM32程序烧录总结

    1.程序烧录方式 1)ST-LINK下载 2)SWD下载 SWD对应的引脚为:GND.RST.SWDIO.SWDCLK SWD与Jlink的比较 3)串口下载 串口下载不能直接在MDK点击Downlo ...

  5. Nuxt配置动态路由以及参数校验

    动态路由就是带参数的路由.比如我们商品列表里很多商品详细页,这时候就需要动态路由的帮助了. 比如我们新建一个commodity文件夹,新建一个index.vue 文件,然后新建一个_id.vue (以 ...

  6. 每天进步一点点------altium designer 实用的快捷键

    1.设计浏览器快捷键: 鼠标左击                         选择鼠标位置的文档鼠标双击                         编辑鼠标位置的文档鼠标右击        ...

  7. yii2 gii开启

    gii模块可以通过配置yii\base\Application::modules属性开启它.在config/web.php文件中会有以下配置代码: $config = [ ... ]; if (YII ...

  8. 移动APP漏洞自动化检测平台建设

    移动APP漏洞自动化检测平台建设   前言:本文是<移动APP客户端安全笔记>系列原创文章中的第一篇,主要讲的是企业移动APP自动化漏洞检测平台建设,移动APP漏洞检测发展史与前沿技术,A ...

  9. jmeter实现SMTP邮件协议压测

    实现目的 通过jmeter的SMTP取样器,调用SMTP协议,批量进行邮件的发送,已达到压测的目的. 脚本实现 User Defined Variables定义用户变量 编辑SMTP Sampler取 ...

  10. Linux按文件名搜索命令

    find 搜索目录 -name 目标名字 find / -name file名 /代表是全盘搜索,也可以指定目录搜索 find 搜索文件的命令格式: find [搜索范围] [匹配条件] 选项: -n ...