3

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);
    }
}
Community
  • 1
  • 1
fracz
  • 20,536
  • 18
  • 103
  • 149

2 Answers2

5

When using Spring Boot, just having a bean as below would also work.

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {

    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setJsonPrefix(")]}',\n");
    return converter;

}

Here is an example from the Spring Lemon project.

Sanjay
  • 8,755
  • 7
  • 46
  • 62
2

Actually, I resolved the root problem (adding the )]}',\n prefix to every JSON response) with the following configuration.

@Configuration
@EnableWebMvc
public class WebappConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setJsonPrefix(")]}',\n");
        converters.add(converter);
    }
}
fracz
  • 20,536
  • 18
  • 103
  • 149