【问题标题】:StrictHttpFirewall in spring security 4.2 vs spring MVC @MatrixVariableSpring Security 4.2 中的 StrictHttpFirewall 与 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

我猜它是向后移植的?

【问题讨论】:

  • 这里是如何允许分号:

标签: spring-mvc spring-security


【解决方案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"/>

&lt;bean&gt; 部分定义了一个新的 StrictHttpFirewall bean,其 id 为 allowSemicolonHttpFirewall,然后通过引用该 id 在 &lt;security&gt; 标记中将其设置为默认 http-firewall。

【讨论】:

    【解决方案3】:

    我使用了以下两个的组合

    1. https://stackoverflow.com/a/48636757/6780127
    2. https://stackoverflow.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 = "/test{num}")
    @ResponseBody
    public ResponseEntity<String> getDetail(@MatrixVariable String num){
        return new ResponseEntity<>("test"+num, HttpStatus.OK);
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-11
      • 2019-01-19
      • 2019-09-25
      • 2018-04-15
      • 2017-04-14
      • 2013-07-17
      • 2014-03-25
      • 2012-12-05
      • 2011-01-08
      相关资源
      最近更新 更多