Java 为什么ESAPI ClickjackFilter必须位于SiteMesh筛选器之后?

Java 为什么ESAPI ClickjackFilter必须位于SiteMesh筛选器之后?,java,owasp,sitemesh,esapi,clickjacking,Java,Owasp,Sitemesh,Esapi,Clickjacking,我们有一个使用OpenSymphony SiteMesh组装页面的应用程序,我们还添加了OWASP ESAPI ClickjackFilter,将X-FRAME-OPTIONS标题添加到响应中 但是,只有当ClickjackFilter映射位于web.xml中的SiteMeshFilter映射之后时,它才起作用。如果首先出现clickjacking过滤器,则不会添加X-FRAME-OPTIONS标题 这项工作: <filter-mapping> <filter-name

我们有一个使用OpenSymphony SiteMesh组装页面的应用程序,我们还添加了OWASP ESAPI ClickjackFilter,将X-FRAME-OPTIONS标题添加到响应中

但是,只有当ClickjackFilter映射位于web.xml中的SiteMeshFilter映射之后时,它才起作用。如果首先出现clickjacking过滤器,则不会添加X-FRAME-OPTIONS标题

这项工作:

<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>

点击顶升过滤器
/*
网站
/网/*

为什么这两个过滤器的顺序很重要?

在我看来,我认为这是因为ESAPI
ClickjackFilter的doFilter()
方法写得不正确。它是这样实现的:

public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)抛出IOException、ServletException
{
HttpServletResponse res=(HttpServletResponse)响应;
链式过滤器(请求、响应);
res.addHeader(“X帧选项”,模式);
}
但是,由于它是一个输出过滤器,因此应该首先使用类似于
HttpServletResponseWrapper的东西包装响应。我认为应该这样写:

public void doFilter(ServletRequest请求、ServletResponse响应、FilterChain链)抛出IOException、ServletException
{
HttpServletRes=
新的javax.servlet.http.HttpServletResponseWrapper(
(HttpServletResponse)响应);
链.doFilter(请求,res);
res.addHeader(“X帧选项”,模式);
}
如果是这样写的,我认为不管应用的顺序如何,它都应该有效


警告:请注意,我根本没有验证这一点(事实上,我甚至没有尝试编译它!),但我认为这可能是错误的。从理论上讲,SiteMesh过滤器也可以做一些令人生厌的事情,但我认为这不太可能。如果有人确认这是错误的,请告诉我,我将提交一份ESAPI错误报告。

看起来已经有一个针对这一问题的错误提交(附带一个假定的修复,顺便说一句,我还没有测试或以其他方式确认)。错误ID是289。详细信息位于:

通常xml是按照指定的顺序处理的,因此可能发生的情况是sitemesh为该标题设置了自己的选项,这就是为什么如果首先加载clickjack筛选器,它可能会被sitemesh的选项破坏。我认为您的做法是正确的。但是,如果我创建了一个自定义类,使用的代码与在中公布的代码相同(但使用的是不同的包),那么这似乎也能正常工作。只有当我使用开箱即用的ClickjackFilter(出现在SiteMesh之前)时,标题才不会出现。是的,我想这也行。此外,在上面的示例中,我可能应该使用HttpServletResponse.setHeader()而不是addHeader(),以确保如果过滤器链中的任何中间JavaEE过滤器添加了X-FRAME-OPTIONS,则会覆盖它。这是不可能的,但可能的,而且只可能导致两种使用不同模式的混淆。我想链中的后续过滤器也可以做同样的事情(使用相同的X-FRAME-OPTIONS标题再次调用setHeader()或addHeader()),但是如果您要使用过滤器,您可能应该知道它在做什么。