Java防止XSS攻击

方法一:转义存储:添加XssFilter 

1.在web.xml添加过滤器:

   <!-- 解决xss漏洞 -->
    <filter>
        <filter-name>xssFilter</filter-name>
        <filter-class>XXXXXX.XssFilter</filter-class>
    </filter>
    <!-- 解决xss漏洞 -->
    <filter-mapping>
        <filter-name>xssFilter</filter-name>
        <url-pattern>*</url-pattern>
    </filter-mapping>

2.添加XssFilter

public class XssFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //使用包装器
        XssFilterWrapper xssFilterWrapper=new XssFilterWrapper((HttpServletRequest) servletRequest);
        filterChain.doFilter(xssFilterWrapper,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

3、添加 XssFilterWrapper.java类

public class XssFilterWrapper  extends HttpServletRequestWrapper {


    public XssFilterWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getHeader(String name) {
        return StringEscapeUtils.escapeHtml4(super.getHeader(name));
    }

    @Override
    public String getQueryString() {
        return StringEscapeUtils.escapeHtml4(super.getQueryString());
    }

    @Override
    public String getParameter(String name) {
        return StringEscapeUtils.escapeHtml4(super.getParameter(name));
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if(values != null) {
            int length = values.length;
            String[] escapseValues = new String[length];
            for(int i = 0; i < length; i++){
                escapseValues[i] = StringEscapeUtils.escapeHtml4(values[i]);
            }
            return escapseValues;
        }
        return super.getParameterValues(name);
    }

}

自此,即能实现,

假如在网站的文本框输入<script>alert("OK");</script>,

提交到数据库后保存的数据为:&amp;lt;script&amp;gt;alert(&amp;quot;OK&amp;quot;);&amp;lt;/script&amp;gt;

 

二、

1.添加XssFilter ,(同上)

2..添加XssHttpServletRequestWrapper.java类

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request The request to wrap
     * @throws IllegalArgumentException if the request is null
     */
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);
        if(StringUtils.isEmpty(value)){
            return value;
        }
        else{
            return cleanXSS(value);
        }

    }

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        if(StringUtils.isEmpty(value)){
            return value;
        }
        else{
            return cleanXSS(value);
        }
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (values != null) {
            int length = values.length;
            String[] escapseValues = new String[length];
            for (int i = 0; i < length; i++) {
                escapseValues[i] = cleanXSS(values[i]);
            }
            return escapseValues;
        }
        return super.getParameterValues(name);
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        String str=getRequestBody(super.getInputStream());
        Map<String,Object> map= JSON.parseObject(str,Map.class);
        Map<String,Object> resultMap=new HashMap<>();
        for(String key:map.keySet()){
            Object val=map.get(key);
            if(map.get(key) instanceof String){
                resultMap.put(key,cleanXSS(val.toString()));
            }
            else{
                resultMap.put(key,val);
            }

        }
        str=JSON.toJSONString(resultMap);
        final ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes());

        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }
        };
    }

    private String getRequestBody(InputStream stream) {
        String line = "";
        StringBuilder body = new StringBuilder();
        int counter = 0;

        // 读取POST提交的数据内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charset.forName("UTF-8")));
        try {
            while ((line = reader.readLine()) != null) {

                body.append(line);
                counter++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return body.toString();
    }
    private String cleanXSS(String value) {
        if(StringUtils.isEmpty(value)){
            return value;
        }
        else{
            if (value != null) {
                if (value != null) {
                    // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
                    // avoid encoded attacks.
                    // value = ESAPI.encoder().canonicalize(value);
                    // Avoid null characters
                    value = value.replaceAll("", "");
                    // Avoid anything between script tags
                    Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
                    value = scriptPattern.matcher(value).replaceAll("");
                    // Avoid anything in a src="http://www.yihaomen.com/article/java/..." type of e­xpression
                    // 会误伤百度富文本编辑器
//                    scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
//                    value = scriptPattern.matcher(value).replaceAll("");
//                    scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
//                    value = scriptPattern.matcher(value).replaceAll("");
                    // Remove any lonesome </script> tag
                    scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
                    value = scriptPattern.matcher(value).replaceAll("");
                    // Remove any lonesome <script ...> tag
                    scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                    value = scriptPattern.matcher(value).replaceAll("");
                    // Avoid eval(...) e­xpressions
                    scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                    value = scriptPattern.matcher(value).replaceAll("");
                    // Avoid e­xpression(...) e­xpressions
                    scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                    value = scriptPattern.matcher(value).replaceAll("");
                    // Avoid javascript:... e­xpressions
                    scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
                    value = scriptPattern.matcher(value).replaceAll("");
                    // Avoid vbscript:... e­xpressions
                    scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
                    value = scriptPattern.matcher(value).replaceAll("");
                    // Avoid onload= e­xpressions
                    scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
                    value = scriptPattern.matcher(value).replaceAll("");
                }
            }
            return value;
        }
    }
}

两种方法,原理一致只是写法不一样,

第二种写法保存到数据库为:scriptalert("OK");/script

 

posted @ 2019-05-28 21:14  Sky—yong  阅读(10494)  评论(1编辑  收藏  举报