Spring Security 4.2 中的 StrictHttpFirewall 与 Spring MVC @MatrixVariable
Posted
技术标签:
【中文标题】Spring Security 4.2 中的 StrictHttpFirewall 与 Spring MVC @MatrixVariable【英文标题】:StrictHttpFirewall in spring security 4.2 vs spring MVC @MatrixVariable 【发布时间】:2018-07-12 19:56:26 【问题描述】:升级到 spring security 4.2.4 后,我发现 StrictHttpFirewall 现在是默认设置。 不幸的是,它不能很好地与 spring MVC @MatrixVariable 一起使用,因为“;”不再被允许。 如何解决这个问题?
例子:
@GetMapping(path = "/param")
public void example(@PathVariable String param,
@MatrixVariable Map<String, String> matrix)
//...
这可以这样调用:
mockMvc.perform(get("/someparam;key=value"))
矩阵图将被填充。 现在 spring 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:140)
我可以使用允许分号的自定义 HttpFirewall。 有没有办法在不使用禁止字符的情况下使用@MatrixVariable?
顺便说一句:javadoc 不正确https://docs.spring.io/autorepo/docs/spring-security/4.2.x/apidocs/index.html?org/springframework/security/web/firewall/StrictHttpFirewall.html
自:
5.0.1
我猜它是向后移植的?
【问题讨论】:
这里是如何允许分号:您可以使用自定义的 StrictHttpFirewall 实例稀释默认的 spring 安全防火墙(风险自负)
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall()
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
firewall.setAllowSemicolon(true);
return firewall;
然后在WebSecurity中使用这个自定义的防火墙bean(Spring boot不需要这个改动)
@Override
public void configure(WebSecurity web) throws Exception
super.configure(web);
// @formatter:off
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
...
这适用于 Spring Security 4.2.4+,但当然会带来一些风险!
【讨论】:
StrictHttpFirewall 阻止请求,因为允许它们是危险的。由于 Servlet 规范中的模糊性以及 Servlet 容器之间的不一致行为(没有拒绝 URL 编码的分号),我们无法找到防止此类攻击的好方法。 那么 Spring MVC @MatrixVariable 也必须更改。 由于某种原因,它不适用于 Spring Security 5.0.3.RELEASE。 不需要在configure(WebSecurity web)
方法中连接bean,因为WebSecurity
实例尝试使用ApplicationContextAware
注释在上下文中查找HttpFirewall
类型的bean。换句话说,仅仅实例化一个 HttpFirewall
类型的 bean 就足够了。
有什么风险?有人可以解释一下为什么这是必要的吗?【参考方案2】:
正如Крис 在评论中提到的,如果您更喜欢使用 XML 方法,您可以将以下部分添加到您的 securityContext.xml(或任何与 spring-security 相关的 xml-config 调用):
<bean id="allowSemicolonHttpFirewall"
class="org.springframework.security.web.firewall.StrictHttpFirewall">
<property name="allowSemicolon" value="true"/>
</bean>
<security:http-firewall ref="allowSemicolonHttpFirewall"/>
<bean>
部分定义了一个新的 StrictHttpFirewall
bean,其 id 为 allowSemicolonHttpFirewall
,然后通过引用该 id 在 <security>
标记中将其设置为默认 http-firewall。
【讨论】:
【参考方案3】:我使用了以下两个的组合
-
https://***.com/a/48636757/6780127
https://***.com/a/30539991/6780127
第一个解决了
The request was rejected because the URL contained a potentially malicious String ";"
第二个解决了
Spring MVC Missing matrix variable
当我将 Spring Security 与 Spring Web 一起使用时,我必须同时做这两个问题,现在问题已解决。
我发现使用@MatrixVariable
跟随模式很有用。首先在 Url 中必须提到 num
才能将其用作 @MatrixVariable
@RequestMapping(method = RequestMethod.GET,value = "/testnum")
@ResponseBody
public ResponseEntity<String> getDetail(@MatrixVariable String num)
return new ResponseEntity<>("test"+num, HttpStatus.OK);
【讨论】:
以上是关于Spring Security 4.2 中的 StrictHttpFirewall 与 Spring MVC @MatrixVariable的主要内容,如果未能解决你的问题,请参考以下文章