Spring Boot escape characters at Request Body for XSS protection

11,475

I resolved with a custom class:

@Configuration
public class AntiXSSConfig  {

    @Autowired()
    public void configeJackson(ObjectMapper mapper) {
        mapper.getFactory().setCharacterEscapes(new HTMLCharacterEscapes());
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static class HTMLCharacterEscapes extends JsonpCharacterEscapes {

        @Override
        public int[] getEscapeCodesForAscii() {
            int[] asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON();
            // and force escaping of a few others:
            asciiEscapes['<'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['>'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['&'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['"'] = CharacterEscapes.ESCAPE_CUSTOM;
            asciiEscapes['\''] = CharacterEscapes.ESCAPE_CUSTOM;
            return asciiEscapes;
        }

        @Override
        public SerializableString getEscapeSequence(int ch) {
            switch (ch) {
                case '&' : return new SerializedString("&#38;");
                case '<' : return new SerializedString("&#60;");
                case '>' : return new SerializedString("&#62;");
                case '\"' : return new SerializedString("&#34;");
                case '\'' : return new SerializedString("&#39;");
                default : return super.getEscapeSequence(ch);
            }
        }
    }
}

It covers all the cases.

Share:
11,475
renanleandrof
Author by

renanleandrof

Updated on June 07, 2022

Comments

  • renanleandrof
    renanleandrof almost 2 years

    I'm trying to secure my spring boot application using a XSSFilter like this:

    public class XSSFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException { }
    
        @Override
        public void destroy() { }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
        }
    
    }
    

    And the wrapper:

    public class XSSRequestWrapper extends HttpServletRequestWrapper {
    
        public XSSRequestWrapper(HttpServletRequest servletRequest) {
            super(servletRequest);
        }
    
        @Override
        public String[] getParameterValues(String parameter) {
            String[] values = super.getParameterValues(parameter);
    
            if (values == null) {
                return null;
            }
    
            int count = values.length;
            String[] encodedValues = new String[count];
            for (int i = 0; i < count; i++) {
                encodedValues[i] = replaceXSSCharacters((values[i]));
            }
    
            return encodedValues;
        }
    
        private String replaceXSSCharacters(String value) {
            if (value == null) {
                return null;
            }
    
            return value
                    .replace("&","&#38;")
                    .replace("<", "&#60;")
                    .replace(">","&#62;")
                    .replace("\"","&#34;")
                    .replace("'","&#39;");
        }
    
        @Override
        public String getParameter(String parameter) {
            return replaceXSSCharacters(super.getParameter(parameter));
        }
    
        @Override
        public String getHeader(String name) {
            return replaceXSSCharacters(super.getHeader(name));
        }
    
    }
    

    The problem is, that only secures the Request parameters and Headers, not the Request body, and sometimes my Controller receive data using @RequestBody.

    So, if i submit to my controller a json like this:

    {"name":"<script>alert('hello!')</script>"}
    

    The html chars at the name property doesn't get escaped like i need. How can i escape the RequestBody?

    EDIT: This is different from the "duplicated" question. My question is very Specific. How to escape characters on Request Body.