为什么 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