今天有个接口打算使用矩阵变量来绑定参数,即使用@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. calloc函数的使用和对内存free的认识

    #include<stdlib.h> void *calloc(size_t n, size_t size): free(); 目前的理解:  n是多少个这样的size,这样的使用类似有f ...

  2. php自制工具函数,常用的函数集合

    字符串与爬虫相关 1,解析url /** * 模拟访问,可get可post * @param $curl * @param $postInfo post数组/字符串,不填默认没有post * @par ...

  3. CSS input

    去除激活 input 的默认边框 // 三种方法都能实现 input{ outline: none; outline: medium; outline:; }   修改光标颜色 input{ outl ...

  4. IntelliJ IDEA 2017.3尚硅谷-----自动导包

  5. VS Code 配置 C/C++ (Windwos)

    下载VSCode https://code.visualstudio.com/Download 在扩展里安装C/C++插件 配置MinGW 需要再环境变量中的path中添加MinGW的bin目录 修改 ...

  6. DataTable 数据批量写入数据库三种方法比较

    DataTable数据批量写入数据库三种方法比较 1)   insert循环插入: 2)   sqldataadapter.update(dataset,tablename); 3)   sqlbul ...

  7. 【应急响应】Linux安全加固

    一.补丁管理 1.查看系统信息 uname -a 2.配置yun源 CentosOS 可以直接升级 RHEL系列可以配置使用CentosOS源 3.升级软件包 yum –y update 二.安全工具 ...

  8. pods " xxxx" not found错误

    pods " xxxx" not found错误 待办 https://linuxacademy.com/community/show/29447-pod-is-not-found ...

  9. maven 项目搭建

    转自:https://www.cnblogs.com/lzx2509254166/p/7674455.html Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软 ...

  10. RAID 0实验:mdadm

    *独立冗余磁盘阵列---RAID0* RAID0: 把多块物理硬盘设备(至少两块)通过硬件或软件的方式串联在一起, 组成 一个大的卷组,并将数据依次写入到各个物理硬盘中.任意一块 硬盘发生故障将导致整 ...