如何在每个Spring JSON响应之前添加")]}',\n"以防止常见漏洞

fra*_*acz 3 java spring servlets servlet-filters

我想为")]}',\n"servlet生成的所有JSON响应添加一个前缀,以防止AngularJS建议的 JSON漏洞.我找到了一种修改响应内容的方法.使用OncePerRequestFilterSpring 的基类,我最终得到:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,当我引入响应包装器时,Content-Type标头(以及其他几个)从响应中消失了.我已经确认,如果没有包装器,response.getHeaderNames()调用将返回14个不同的头文件(包括内容类型),而使用包装器时,只有9个.它还会破坏字符编码,因为使用包装器时,Content-Type头文件不会告诉浏览器内容是在UTF-8中.为什么?


CharResponseWrapper 这里这里的来源和想法.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

San*_*jay 5

使用Spring Boot时,只需使用下面的bean也可以.

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {

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

}
Run Code Online (Sandbox Code Playgroud)

Spring Lemon项目的一个例子.