【问题标题】:Tomcat 7 and CSRF filterTomcat 7 和 CSRF 过滤器
【发布时间】:2014-07-24 19:35:47
【问题描述】:

我正在尝试向 Java Web 应用程序添加 CSRF 保护。我用 CSRF 过滤器和过滤器映射到 servlet 配置了 web.xml。 但是,我不确定下一部分该怎么做。文档说返回给客户端的所有 URL 都是通过调用 HttpServletResponse#encodeRedirectURL(String) 或 HttpServletResponse#encodeURL(String) 进行编码的 他们还说您可以尝试: 或者可以将 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">

我做错了什么?

【问题讨论】:

  • 我们也有同样的问题。有人得到解决方案吗?

标签: tomcat tomcat7 csrf csrf-protection


【解决方案1】:

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

的URL

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

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

  1. 首先,当客户端访问应用程序时,请求的 URL 必须由过滤器映射并匹配 entryPoints 之一。这样CsrfPreventionFilter 可以生成一个新的随机数存储到会话中包装响应覆盖HttpServletResponse#encodeRedirectURL(String)HttpServletResponse#encodeURL(String),而不阻塞请求(通过返回 403)。
  2. 页面中的 URL 应使用HttpServletResponse#encodeRedirectURL(String) or HttpServletResponse#encodeURL(String) 编码,就像您在表单操作中所做的那样。实际上,“编码”就是在请求参数名称“org.apache.catalina.filters.CSRF_NONCE”后附加一个filter在第一步中生成的nonce值。
  3. 当客户端访问页面中已编码的 URL 时,CsrfPreventionFilter 将检查请求是否有效——nonce 是否与当前会话中存储的其中之一匹配(使用大小为 5 默认的 LRUCache,可以通过 init-param nonceCacheSize) 设置。

因此,除非您声明的 servlet exampleservlet 也映射到“/*”或“/html,/html/”,并且 /html 可能会导致页面包含表单,否则您的代码将无法工作。

因为你在

中使用的响应

&lt;FORM METHOD="POST" ACTION="&lt;%=response.encodeURL("/exampleservlet")%&gt;"&gt;

没有被CsrfPreventionFilter 包裹,也不会魔法附加随机数。

没有

&lt;INPUT TYPE="HIDDEN" NAME="org.apache.catalina.filters.CSRF_NONCE" VALUE="&lt;%=session.getAttribute("org.apache.catalina.filters.CSRF_NONCE")%&gt;"&gt;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-20
    • 2015-03-28
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 2015-05-22
    • 2011-11-27
    • 2015-06-11
    相关资源
    最近更新 更多