I want to add a ")]}',\n"
prefix to all JSON responses produced by servlet in order to prevent JSON vulnerability as AngularJS suggests. I found a way to modify the response content. Using the OncePerRequestFilter
base class from Spring, I have end up with:
public class JsonArrayVulnerabilityPreventorFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
PrintWriter responseOut = response.getWriter();
CharResponseWrapper responseWrapper = new CharResponseWrapper(response);
filterChain.doFilter(request, responseWrapper);
if (StringUtils.contains(responseWrapper.getHeader("Content-Type"), "application/json")) {
responseOut.write(")]}',\n");
}
String originalServletResponse = responseWrapper.toString();
responseOut.write(originalServletResponse);
}
}
The problem is that when I have introduced the response wrapper, the Content-Type
header (and few others) disappeared from the response. I have confirmed that without a wrapper, the response.getHeaderNames()
call returns 14 different headers (including content type) whereas with the wrapper, there is only 9. It also breaks character encoding, because with the wrapper the Content-Type
header does not tell the browser that the content is in UTF-8. Why?
Source and idea of the CharResponseWrapper
here and here.
public class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public CharResponseWrapper(HttpServletResponse response) {
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter() {
return new PrintWriter(output);
}
}