개발 이야기

xss - parameter & post raw body filter

요령도사 2021. 10. 21. 10:28
반응형

xss - post raw body filter

@ pom.xml

        <dependency>
            <groupId>com.navercorp.lucy</groupId>
            <artifactId>lucy-xss-servlet</artifactId>
            <version>2.0.0</version>
        </dependency>

@ web.xml

    <filter>
        <filter-name>xssEscapeServletCustomFilter</filter-name>
        <filter-class>com.hm.netis.common.secure.XssEscapeServletCustomFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>xssEscapeServletCustomFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

@ class

import com.nhncorp.lucy.security.xss.XssFilter;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

public class HttpServletRequestBodyWrapper extends HttpServletRequestWrapper {

    private String body;
    private XssFilter xssFilter;

    public HttpServletRequestBodyWrapper(ServletRequest request, XssFilter xssFilter) throws IOException {
        super((HttpServletRequest) request);
        this.xssFilter = xssFilter;
        body = xssFilter.doFilter(getBody((HttpServletRequest) request));
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream bis = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStreamImpl(bis);
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    private String getBody(HttpServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();

        try (
                InputStream inputStream = request.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))
        ) {
            char[] charBuffer = new char[128];
            int bytesRead = -1;
            while ((bytesRead = br.read(charBuffer)) > 0) {
                sb.append(charBuffer, 0, bytesRead);
            }
        }
        return sb.toString();
    }

    class ServletInputStreamImpl extends ServletInputStream {
        private InputStream is;

        public ServletInputStreamImpl(InputStream bis) {
            is = bis;
        }

        public int read() throws IOException {
            return is.read();
        }

        public int read(byte[] b) throws IOException {
            return is.read(b);
        }
    }
}​
import javax.servlet.*;
import java.io.IOException;

public class XssEscapeServletCustomFilter implements Filter {

    private com.navercorp.lucy.security.xss.servletfilter.XssEscapeFilter xssEscapeFilter = com.navercorp.lucy.security.xss.servletfilter.XssEscapeFilter.getInstance();
    private com.nhncorp.lucy.security.xss.XssFilter xssFilter = com.nhncorp.lucy.security.xss.XssFilter.getInstance("lucy-xss-servlet-filter-rule.xml");

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        if (isRequestBody(req)) {
            chain.doFilter(new HttpServletRequestBodyWrapper(req, xssFilter), res);
        } else {
            chain.doFilter(new com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilterWrapper(req, xssEscapeFilter), res);
        }
    }

    private boolean isRequestBody(ServletRequest req) {
        return java.util.Objects.nonNull(req.getContentType()) && req.getContentType().contains(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }
}
반응형