为什么 ESAPI ClickjackFilter 必须在 SiteMesh 过滤器之后?
Why does the ESAPI ClickjackFilter have to come after the SiteMesh filter?
我们有一个使用 OpenSymphony SiteMesh 到 assemble 页面的应用程序,我们添加了 OWASP ESAPI ClickjackFilter 以将 X-FRAME-OPTIONS header 添加到响应中。
但是,只有当 ClickjackFilter 映射出现在 web.xml 中的 SiteMeshFilter 映射之后时,它才有效。如果点击劫持过滤器首先出现,则不会添加 X-FRAME-OPTIONS header。
这个有效:
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/web/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Clickjacking filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这行不通:
<filter-mapping>
<filter-name>Clickjacking filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/web/*</url-pattern>
</filter-mapping>
为什么这两个过滤器的顺序很重要?
在我看来,我认为是因为ESAPIClickjackFilter's doFilter()
方法写错了。它是这样实现的:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletResponse res = (HttpServletResponse)response;
chain.doFilter(request, response);
res.addHeader("X-FRAME-OPTIONS", mode );
}
但是,因为它是一个 output 过滤器,它应该首先使用 HttpServletResponseWrapper
之类的东西包装响应。我觉得应该这样写:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletResponse res =
new javax.servlet.http.HttpServletResponseWrapper(
(HttpServletResponse)response );
chain.doFilter(request, res);
res.addHeader("X-FRAME-OPTIONS", mode );
}
如果以这种方式编写,我认为无论应用顺序如何,它都应该可以工作。
CAVEAT:请注意,我根本没有验证这一点(事实上,我什至没有尝试编译它!),但我认为这可能是什么是错的。理论上,SiteMesh 过滤器也可以做一些时髦的事情,但我认为这种可能性较小。如果有人确认这是错误的,请告诉我,我会提交一份 ESAPI 错误报告。
看起来已经有一个针对此的错误(有一个假定的修复,顺便说一句,我没有测试或以其他方式确认)。错误 ID 为 289。详细信息位于:https://github.com/ESAPI/esapi-java-legacy/issues/289
我们有一个使用 OpenSymphony SiteMesh 到 assemble 页面的应用程序,我们添加了 OWASP ESAPI ClickjackFilter 以将 X-FRAME-OPTIONS header 添加到响应中。
但是,只有当 ClickjackFilter 映射出现在 web.xml 中的 SiteMeshFilter 映射之后时,它才有效。如果点击劫持过滤器首先出现,则不会添加 X-FRAME-OPTIONS header。
这个有效:
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/web/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Clickjacking filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这行不通:
<filter-mapping>
<filter-name>Clickjacking filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/web/*</url-pattern>
</filter-mapping>
为什么这两个过滤器的顺序很重要?
在我看来,我认为是因为ESAPIClickjackFilter's doFilter()
方法写错了。它是这样实现的:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletResponse res = (HttpServletResponse)response;
chain.doFilter(request, response);
res.addHeader("X-FRAME-OPTIONS", mode );
}
但是,因为它是一个 output 过滤器,它应该首先使用 HttpServletResponseWrapper
之类的东西包装响应。我觉得应该这样写:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
HttpServletResponse res =
new javax.servlet.http.HttpServletResponseWrapper(
(HttpServletResponse)response );
chain.doFilter(request, res);
res.addHeader("X-FRAME-OPTIONS", mode );
}
如果以这种方式编写,我认为无论应用顺序如何,它都应该可以工作。
CAVEAT:请注意,我根本没有验证这一点(事实上,我什至没有尝试编译它!),但我认为这可能是什么是错的。理论上,SiteMesh 过滤器也可以做一些时髦的事情,但我认为这种可能性较小。如果有人确认这是错误的,请告诉我,我会提交一份 ESAPI 错误报告。
看起来已经有一个针对此的错误(有一个假定的修复,顺便说一句,我没有测试或以其他方式确认)。错误 ID 为 289。详细信息位于:https://github.com/ESAPI/esapi-java-legacy/issues/289