我正在尝试使用过滤器来检查响应正文中的 HTML 标记。问题是,如果我改变过滤器中的主体,当它到达客户端时它不会改变。我尝试了此处显示的解决方案:寻找使用 servlet 过滤器将内容插入响应的示例 https://stackoverflow.com/questions/14736328/looking-for-an-example-for-inserting-content-into-the-response-using-a-servlet-f但这没有帮助。
我有两个过滤器。SecureWrapperFilter
将请求/响应对象包装在我们的自定义包装器中,并且XSSFilter
使用 OWASP 编码对 html 内容进行编码。过滤器看起来像这样:
public class SecureWrapperFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response,
final FilterChain chain) throws IOException, ServletException
{
final ServletRequestWrapper securityRequest =
new ServletRequestWrapper((HttpServletRequest)request);
final ServletResponseWrapper securityResponse =
new ServletResponseWrapper((HttpServletResponse)response);
ESAPI.httpUtilities().setCurrentHTTP(securityRequest, securityResponse);
chain.doFilter(ESAPI.currentRequest(), ESAPI.currentResponse());
}
@Override
public void destroy() {
}
}
and:
public class XSSFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response,
final FilterChain chain) throws IOException, ServletException
{
final ServletRequestWrapper requestWrapper = (ServletRequestWrapper)request;
final String body = Encode.forHtmlContent(requestWrapper.getBody());
requestWrapper.setBody(body);
chain.doFilter(requestWrapper, response);
final ServletResponseWrapper responseWrapper = (ServletResponseWrapper)response;
final byte[] copy = responseWrapper.getCopy();
final String oldBody = new String(copy, response.getCharacterEncoding());
final String newBody = Encode.forHtmlContent(oldBody);
if (!StringUtils.equals(oldBody, newBody)) {
responseWrapper.getResponse().getOutputStream().write(newBody.getBytes());
}
}
@Override
public void destroy() {
}
}
如果我添加一些调试日志记录,我可以看到securityResponse
SecureWrapperFilter 中有修改后的主体,但在客户端,主体看起来好像从未被修改过。
任何建议将不胜感激。谢谢。