Tomcat 7和CSRF过滤器

时间:2014-07-24 19:35:48

标签: tomcat tomcat7 csrf csrf-protection

我正在尝试将CS​​RF保护添加到java Web应用程序中。我有web.xml配置了CSRF过滤器和过滤器到servlet的映射。 但是,我不知道下一部分该怎么做。文档说通过调用HttpServletResponse#encodeRedirectURL(String)或HttpServletResponse #creditURL(String)来编码返回给客户端的所有URL 他们还说你可以尝试: 或者可以将nonce作为请求参数传回,名称为org.apache.catalina.filters.CSRF_NONCE,这是常量org.apache.catalina.filters.Constants.CSRF_NONCE_REQUEST_PARAM的值。

更新 我仍然被禁止获得403。有人有什么建议吗? 这是web.xml设置:

<filter>
    <filter-name>CSRF</filter-name>
    <filter-class>org.apache.catalina.filters.CsrfPreventionFilter</filter-class>
    <init-param>
      <param-name>entryPoints</param-name>
      <param-value>/html,/html/</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CSRF</filter-name>
    <servlet-name>exampleservlet</servlet-name>
  </filter-mapping>

这是JSP页面代码

<FORM METHOD="POST"  ACTION="<%=response.encodeURL("/exampleservlet")%>">
        <INPUT TYPE="HIDDEN" NAME="org.apache.catalina.filters.CSRF_NONCE" VALUE="<%=session.getAttribute("org.apache.catalina.filters.CSRF_NONCE")%>">
        <INPUT TYPE="HIDDEN" NAME="id" VALUE="0">

我做错了什么?

1 个答案:

答案 0 :(得分:5)

我认为现在这个问题不再重要,因为这个问题是在几年前提出的,但我偶尔会访问它以获得org.apache.catalina.filters.CsrfPreventionFilter的使用提示。 如tomcat官方网站CSRF_Prevention_Filter中的文档所述,假设CsrfPreventionFilter映射到“/ *”,并使用名为“entryPoints”的init-param来保存

  

提供了一种在导航远离它后导航回受保护应用程序的方法

我将尝试以简单的方式解释CsrfPreventionFilter所做的工作:

  1. 首先,当客户端访问应用程序时,请求的URL必须由过滤器映射并匹配entryPoints之一。因此,CsrfPreventionFilter可以生成新的随机数存储到会话包装响应覆盖HttpServletResponse#encodeRedirectURL(String)和{{ 1}},而不阻止请求(返回403)
  2. 页面中的网址应由HttpServletResponse#encodeURL(String)编码,就像您在表单操作中所做的那样。事实上,“编码”是在第一步中附加一个请求参数名称“org.apache.catalina.filters.CSRF_NONCE”,其值为过滤器生成的随机数。
  3. 当客户端访问页面中编码的URL时,HttpServletResponse#encodeRedirectURL(String) or HttpServletResponse#encodeURL(String)将检查请求是否有效 - nonce是否与当前会话中存储的那些匹配(使用大小为5的LRUCache,可以通过init-param CsrfPreventionFilter)设置。
  4. 因此,除非您声明的servlet nonceCacheSize也映射到“/ *”或“exampleservlet”,并且/ html可能导致页面保存表单,否则您的代码将无效。< / p>

    因为您在

    中使用的回复
      

    /html,/html/

    不会被<FORM METHOD="POST" ACTION="<%=response.encodeURL("/exampleservlet")%>">包裹,也不会用魔法来附加现时。

    不是

      

    CsrfPreventionFilter

    会成功,因为过滤器从未设置过会话属性“org.apache.catalina.filters.CSRF_NONCE”。即使有一个,它也包含一个LRUCache实例,但不包含一个nonce字符串。