I am attempting to use a filter to check for HTML tags in a response body. The problem is that if I alter the body in the filter, it isn't altered when it gets to the client. I tried the solution shown here: Looking for an example for inserting content into the response using a servlet filter but it didn't help.
I have two filters. SecureWrapperFilter
wraps the request/response objects in our custom wrapper, and XSSFilter
uses OWASP encode to encode for html content. The filters look like this:
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() {
}
}
If I add some debug Logging, I can see that the securityResponse
has the modified body in the SecureWrapperFilter, but on the client side, the body looks as if it was never modified.
Any suggestions would be greatly appreciated. Thanks.