防止XSS攻击

2018-10-30  本文已影响0人  Lymen_lcm

关于什么是XSS攻击这里就不说明了,百度一下有很多解释,这里只是做一个自己的修补记录,仅供参考。
这里主要参考了公司的一位大神写的工具类,再做点修改

代码

首页在web.xml里面去添加一个全局拦截器

<!-- xss过滤器 -->
    <filter>
        <filter-name>XssSqlFilter</filter-name>
        <filter-class>com.XXX.common.filter.XSSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>XssSqlFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

然后是filter

package com.XXX.common.filter;

import com.XXX.common.utils.XssUtil;
import com.XXX.common.wrapper.XssHttpServletRequestWrapper;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


 /**
  * 防止xss攻击 过滤器(顺便过滤了 sql攻击)
  * @SINCE 2018/10/30 10:27
  * @AUTHOR LCM
  * @Param
  * @return
  */
public class XSSFilter implements Filter {

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        request.setCharacterEncoding("UTF-8");
        if(request instanceof HttpServletRequest) {
            requestWrapper = new XssHttpServletRequestWrapper((HttpServletRequest) request);
        }
        if(requestWrapper == null) {
            chain.doFilter(request, response);
        } else {
                try {
                    if(XssUtil.existsSQLInject(((XssHttpServletRequestWrapper) requestWrapper).getBody().toString())) {
                        throw new Exception("请求包含非法字符");
                    }else {
                        chain.doFilter(requestWrapper, response);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
//        chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);

    @Override
    public void destroy() {

    }

}

filter引用了工具类XssUtil,XssHttpServletRequestWrapper

package com.XXX.common.utils;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * XSS 防御工具类
 * @since 2015-4-23
 * @author BENSON
 * @version 1.1
 */
public class XssUtil {

    // Log4j日志对象
    private static final Logger logger = Logger.getLogger(XssUtil.class);
    
    // 特殊字符
    public static final String REGEX_SPECIAL_CHARS = "[()+{}]";
    //public static final String REGEX_SPECIAL_CHARS = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]"; 
    // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
    public static final String REGEX_SCRIPT = "[\\<\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; 
    // 定义script的正则表达式<script
    public static final String REGEX_SCRIPT_START = "<script"; 
    // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
    public static final String REGEX_STYLE = "[\\<\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; 
    // 定义HTML标签的正则表达式
    public static final String REGEX_HTML = "<[^>]+>"; 
    // 定义window.location脚本的正则表达式
    public static final String REGEX_LOCATION = "[\\s]*?window.location[\\s]*?|[\\s]*?window\\['location'\\][\\s]*?"; 
    
    // 定义HTML的事件标签,如onclick等方法
    public static String REGEX_HTML_ACTION = "";
    
    //初始化定义HTML的事件标签
    static {
        REGEX_HTML_ACTION += "(";
        
        String regexHtmlActionArray[] = {
                "onblur","onchange","oncontextmenu","onfocus","onformchange",
                "onforminput","oninput","oninvalid","onreset","onselect",
                "onsubmit","onkeydown","onkeypress","onkeyup","onclick",
                "ondblclick","ondrag","ondragend","ondragenter",
                "ondragleave","ondragover","ondragstart","ondrop","onmousedown",
                "onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel",
                "onscroll","onmouseenter","onunload","onload","onabort",
                "onerror","onresize"
        };
        
        for(String regexHtmlAction : regexHtmlActionArray){
            REGEX_HTML_ACTION += "(" + regexHtmlAction + ")|";
        }

        REGEX_HTML_ACTION = REGEX_HTML_ACTION.substring(0, REGEX_HTML_ACTION.length() - 1);
        
        REGEX_HTML_ACTION += ")";
    }
    
    // 定义alert脚本的正则表达式 
    //public static final String REGEX_ALERT = "[\\<\\s]*?alert[\\(\\s]*?[\\)]*?"; 
    
    
    /**
     * 过滤掉HTML可能存在的XSS的标签
     * @param inputString 输入的字符串
     * @return 过滤后的文本
     */
    public static String html2Text(String inputString) {
        String htmlStr = inputString; // 含html标签的字符串
        String textStr = "";
        Pattern p_script;
        Matcher m_script;
        Pattern p_style;
        Matcher m_style;
        /*
         * java.util.regex.Pattern p_html; java.util.regex.Matcher m_html;
         */

        try {
            String regEx_Java = "[J|j][\\s]*[\\n]*[A|a][\\s]*[\\n]*[V|v][\\s]*[\\n]*[A|a][\\s]*[\\n]*";
            String regEx_cookie = "[D|d][\\s]*[\\n]*[O|o][\\s]*[\\n]*[C|c][\\s]*[\\n]*[U|u][\\s]*[\\n]*[M|m][\\s]*[\\n]*[E|e][\\s]*[\\n]*[N|n][\\s]*[\\n]*[T|t][\\s]*[\\n]*\\.[C|c][\\s]*[\\n]*[O|o]{2}[\\s]*[\\n]*[K|k][\\s]*[\\n]*[I|i][\\s]*[\\n]*[E|e][\\s]*[\\n]*";
            String regEx_location = "[W|w][\\s]*[\\n]*[I|i][\\s]*[\\n]*[N|n][\\s]*[\\n]*[D|d][\\s]*[\\n]*[O|o][\\s]*[\\n]*[W|w][\\s]*[\\n]*\\.[L|l][\\s]*[\\n]*[O|o][\\s]*[\\n]*[C|c][\\s]*[\\n]*[A|a][\\s]*[\\n]*[T|t][\\s]*[\\n]*[I|i][\\s]*[\\n]*[O|o][\\s]*[\\n]*[N|n][\\s]*[\\n]*\\s*";
//          String regEx_alert = "[A|a][\\s]*[\\n]*[L|l][\\s]*[\\n]*[E|e][\\s]*[\\n]*[R|r][\\s]*[\\n]*[T|t][\\s]*[\\n]*\\s*\\(.*\\)";
            String regEx_alert = "[A|a][\\s]*[\\n]*[L|l][\\s]*[\\n]*[E|e][\\s]*[\\n]*[R|r][\\s]*[\\n]*[T|t]";
//          String regEx_alert = "alert";
            String regEx_lt_script = "&lt;[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t]&gt;";
            String regEx_gt_script = "&lt;/[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t]&gt;";

            String regEx_script = "<[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
//          String regEx_script = "<script[^>]*?>[\\\\s\\\\S]*?<\\\\/script>";

            String regEx_codescript = "<[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>[\\s\\S]*?<[\\s]*?%2f[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
//          String regEx_codescript = "<script[^>]*?>[\\\\s\\\\S]*?<\\\\/script>";

            String regEx_onlyscript = "&lt;[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>

            String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>

            // String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式

            p_script = Pattern.compile(regEx_Java, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤 java标签
             System.out.println("过滤 java:"+htmlStr);

            p_script = Pattern.compile(regEx_cookie, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤 document.cookie标签
             System.out.println("过滤 cookie:"+htmlStr);

            p_script = Pattern.compile(regEx_location, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤window.location标签

             System.out.println("过滤 location:"+htmlStr);

            p_script = Pattern.compile(regEx_alert, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤alert标签

             System.out.println("过滤 alert:"+htmlStr);

            p_script = Pattern.compile(regEx_lt_script, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤alert标签

             System.out.println("过滤 ltscript:"+htmlStr);

             p_script = Pattern.compile(regEx_gt_script, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤alert标签

             System.out.println("过滤 gtscript:"+htmlStr);

            p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤script标签
             System.out.println("过滤 script:"+htmlStr);

            p_script = Pattern.compile(regEx_codescript,
                    Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤codescript标签
             System.out.println("过滤 regEx_codescript:"+htmlStr);

            p_script = Pattern.compile(regEx_onlyscript,
                    Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤onlyscript标签
             System.out.println("过滤 onlyscript:"+htmlStr);

            p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
            m_style = p_style.matcher(htmlStr);
            htmlStr = m_style.replaceAll(""); // 过滤style标签
             System.out.println("过滤 style:"+htmlStr);

            /*
             * p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
             * m_html = p_html.matcher(htmlStr); htmlStr =
             * m_html.replaceAll(""); // 过滤html标签
             */
            // System.out.println("html:"+htmlStr);

            textStr = htmlStr;

        } catch (Exception e) {
            logger.error("html2Text: " + e.getMessage());
        }

        return textStr;// 返回文本字符串
    }

    /**
     * 将容易引起XSS漏洞的半角字符直接替换成全角字符
     * 
     * @param s 需要转换的文本
     * @return
     */
    public static String xssEncode(String s) {
        if (StringUtil.isNullString(s)) {
            return s;
        }
        
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
            case '>':
                // sb.append("&gt;");//全角大于号
                sb.append(">");// 全角大于号
                break;
            case '<':
                // sb.append("&lt;");//全角小于号
                sb.append("<");// 全角大于号
                break;
            case '\'':
                sb.append('‘');// 全角单引号
                break;
            case '\"':
                // sb.append("&quot;");//全角双引号
                sb.append(""");// 全角双引号
                break;
            case '&':
                // sb.append("&amp;");//全角
                sb.append("&");// 全角
                break;
            case '\\':
                sb.append('\');// 全角斜线
                break;
            case '#':
                sb.append('#');// 全角井号
                break;

            default:
                sb.append(c);
                break;
            }
        }
        return sb.toString();
    }
    

    /**
     * 剔除XSS代码
     * @param value 需要剔除的文本
     * @return 剔除后文本
     */
    public static String stripXSS(String value) {
        // empty handle
        if (StringUtil.isNullString(value)) {
            return value;
        }
       
        // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
        // avoid encoded attacks.
        // value = ESAPI.encoder().canonicalize(value);
        
        // Remove all HTML tag
        value = HtmlStringUtil.Html2Text(value);
        System.out.println("Remove all HTML tag:" + value);
        
        Pattern scriptPattern = null;
        
        // Avoid anything in a src='...' type of e­xpression
        scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", 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("");
        
        // Avoid alert(...) e­xpressions
        scriptPattern = Pattern.compile("alert(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");
        System.out.println("Avoid alert(...) e­xpressions:" + value);
        
        // Avoid document.cookie
        scriptPattern = Pattern.compile("document.cookie", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");
        System.out.println("Avoid document.cookie:" + value);
        
        // Avoid event e­xpressions
        scriptPattern = Pattern.compile("event.*?", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");
        System.out.println("Avoid event e­xpressions:" + value);
        
        // Avoid function(...) e­xpressions
        scriptPattern = Pattern.compile("function(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");
        System.out.println("Avoid function(...) e­xpressions:" + value);
        
        // Avoid toString: e­xpressions
        scriptPattern = Pattern.compile("toString:", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");
        System.out.println("Avoid toString: e­xpressions:" + value);
        
        // Avoid location.href e­xpressions
        scriptPattern = Pattern.compile("location*?[.href][.host]", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");
        System.out.println("Avoid location.href e­xpressions:" + value);
        
        // Avoid Special characters
        scriptPattern = Pattern.compile(REGEX_SPECIAL_CHARS); 
        value = scriptPattern.matcher(value).replaceAll("");
        System.out.println("Avoid Special characters:" + value);

        return value;
    }
    
    
    /**
     * 剔除XSS代码
     * @param value 需要剔除的文本
     * @return 剔除后文本
     */
    public static String escapeXSS(String value) {
        // empty handle
        if (StringUtil.isNullString(value)) {
            return value;
        }
        
        System.out.println("\n---------------------------------------------------------------");
        value = StringEscapeUtils.escapeHtml(value);
        System.out.println("escapeHtml:" + value);
        
        value = StringEscapeUtils.escapeJavaScript(value);
        System.out.println("escapeJavaScript:" + value);
        
        value = StringEscapeUtils.escapeCsv(value);
        System.out.println("escapeCsv:" + value);
        
        value = StringEscapeUtils.escapeXml(value);
        System.out.println("escapeXml:" + value);
        
        value = StringEscapeUtils.escapeSql(value);
        System.out.println("escapeSql:" + value);
        
        value = StringEscapeUtils.escapeJava(value);
        System.out.println("escapeJava:" + value);
        System.out.println("---------------------------------------------------------------\n");
        
        return value;
    }
    
    
    /**
     * 校验是否包含跨站脚本攻击或者SQL注入代码
     * @param input 输入的数据
     * @return 结果:TURE-包含 OR FALSE-不包含
     */
    public static boolean checkXSS(String input) {
        // empty handle
        if (StringUtil.isNullString(input)) {
            return false;
        }
        
        //br标签吞了
        input = input.replaceAll("<br/>", "");
        
        // script脚本匹配
        Matcher scriptMatcher = Pattern.compile(REGEX_SCRIPT, Pattern.CASE_INSENSITIVE).matcher(input);
        if (scriptMatcher.find()) {
            System.out.println("REGEX_SCRIPT XSS");
            return true;
        }
        
        // scriptStart脚本匹配
        scriptMatcher = Pattern.compile(REGEX_SCRIPT_START, Pattern.CASE_INSENSITIVE).matcher(input);
        if (scriptMatcher.find()) {
            System.out.println("REGEX_SCRIPT_START XSS");
            return true;
        }
        
        // style标签匹配
        scriptMatcher = Pattern.compile(REGEX_STYLE, Pattern.CASE_INSENSITIVE).matcher(input);
        if (scriptMatcher.find()) {
            System.out.println("REGEX_STYLE XSS");
            return true;
        }
        // HTML标签匹配
        scriptMatcher = Pattern.compile(REGEX_HTML, Pattern.CASE_INSENSITIVE).matcher(input);
        if (scriptMatcher.find()) {
            System.out.println("REGEX_HTML XSS");
            return true;
        }
        // 特殊字符匹配
//      scriptMatcher = Pattern.compile(REGEX_SPECIAL_CHARS, Pattern.CASE_INSENSITIVE).matcher(input);
//      if (scriptMatcher.find()) {
//          System.out.println("REGEX_SPECIAL_CHARS XSS" + scriptMatcher.group(0));
//          System.out.println(input);
//          return true;
//      }
        // window.location匹配
        scriptMatcher = Pattern.compile(REGEX_LOCATION, Pattern.CASE_INSENSITIVE).matcher(input);
        if (scriptMatcher.find()) {
            System.out.println("REGEX_LOCATION XSS");
            return true;
        }
        
        // html事件标签匹配
        scriptMatcher = Pattern.compile(REGEX_HTML_ACTION, Pattern.CASE_INSENSITIVE).matcher(input);
        if (scriptMatcher.find()) {
            System.out.println("REGEX_HTML_ACTION XSS");
            return true;
        }
        
        boolean isExists = XssUtil.existsSQLInject(input);
        if(isExists) {
            return true;
        }
        
        return false;
    }
    

    /**
     * 判断是否存在SQL注入
     * @param src 当前访问路径
     * @return
     */
    public static boolean existsSQLInject(String src) {  
        if (StringUtil.isNullString(src)) {
            return false;
        }
        
        List<String> list = SqlKeysCache.getSqlKeysList();
        
        String str = src.toLowerCase();
        for (int i = 0; i < list.size(); i++) {
            if (str.contains(list.get(i))) {
                System.out.println("输入信息存在SQL注入攻击!" + list.get(i));
                logger.error("输入信息存在SQL注入攻击!" + list.get(i));
                return true;
            }
        }
        
        return false;  
    }    
    
    
    
    /*public static void main(String[] args) {
        
        String input = null;
        String tips = null;
        
        input = "SCRIPT>var a = document.cookie; alert(a);</SCRIPT>";
        tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
        System.out.println("1" + tips);
        
        input = "style> .input{font-color:red};</style>";
        tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
        System.out.println("2" + tips);
        
        input = "<DIV> <a href='www.baidu.com'>baidu</a></div>";
        tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
        System.out.println("3" + tips);
        
        input = "http://www.lzsmw.net/visit/interactionPage/toPubMailDetail?msgCode=\"&x='abc',new Function(x)()+\"";
        tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
        System.out.println("4" + tips);
        
        input = "http://www.lzsmw.net/visit/approvePage/toOrderWindowFloor?programId=window['location']&asddf";
        tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
        System.out.println("5" + tips);
        
        input = "http://www.lzsmw.net/visit/interactionPage/toPubMailDetail?msgCode=123&param=ok";
        tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
        System.out.println("6" + tips);
        
    }*/
    public static void main(String[] args) {
        String input = "{\"lmType\":{\"type\":\"1\"}}";
        String  ss ="{\"articleInfo\":{\"uuid\":\"\",\"articleId\":\"\",\"articleType\":\"1\"," +
                "\"modifyDate\":\"2018-09-15 18:07\",\"sortId\":\"f39c315d323b4186913665b95fa7a4b7\"," +
                "\"terminal\":\"\",\"title\":\"测试<script>alert(11234)</script>\",\"author\":\"教超管\"," +
                "\"origin\":\"测试<script>alert(11234)</script>\",\"content\":\"<p>测试&lt;script&gt;alert(11234)&lt;" +
                "/script&gt;</p><p>测试&lt;script&gt;alert(134567)&lt;/script&gt;</p><p>测试&lt;script&gt;alert(145555)" +
                "&lt;/script&gt;</p><p>测试&lt;script&gt;alert(157777)&lt;/script&gt;</p><p>测试&lt;script&gt;alert" +
                "(13434324)&lt;/script&gt;</p><p><strong>&lt;131231231231231231231231231231231234123&gt;" +
                "</strong></p><p><strong><br/></strong></p><p><span style=\\\"text-decoration: underline;" +
                "\\\"><strong><br/></strong></span></p><p><span style=\\\"text-decoration: underline;" +
                "\\\"><strong><strong style=\\\"white-space: normal;\\\">&lt;" +
                "131231231231231231231231231231231234123&gt;</strong><strong style=\\\"white-space: normal;\\\">&lt;" +
                "131231231231231231231231231231231234123&gt;</strong><strong>&lt;" +
                "131231231231231231231231231231231234123&gt;</strong><strong>&lt;" +
                "</strong></strong></span><strong><strong>131231231231231231231231231231231234123&gt;" +
                "</strong><strong>&lt;1312312312312312312312312</strong><span style=\\\"color: rgb(147, 137, 83);" +
                "\\\"><strong>31231231234123&gt;</strong><strong>&lt;131231231231231231231231231231231234123&gt;" +
                "</strong><strong>&lt;131231231231231231231231231231231234123&gt;</strong></span></strong></p><p " +
                "style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: " +
                "nowrap; top: 34px;\\\">测试&lt;script&gt;alert(11234)&lt;/script&gt;</p><p style=\\\"position: " +
                "absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 34px;" +
                "\\\"><br/></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: " +
                "-1000px; white-space: nowrap; top: 39px;\\\">测试&lt;script&gt;alert(11234)&lt;/script&gt;</p><p " +
                "style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: " +
                "nowrap; top: 39px;\\\"><br/></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: " +
                "hidden; left: -1000px; white-space: nowrap; top: 44px;\\\">测试&lt;script&gt;alert(11234)&lt;" +
                "/script&gt;</p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: " +
                "-1000px; white-space: nowrap; top: 44px;\\\">测试&lt;script&gt;alert(11234)&lt;/script&gt;</p><p " +
                "style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: " +
                "nowrap; top: 44px;\\\"><br/></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: " +
                "hidden; left: -1000px; white-space: nowrap; top: 49px;\\\">测试&lt;script&gt;alert(11234)&lt;" +
                "/script&gt;</p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: " +
                "-1000px; white-space: nowrap; top: 49px;\\\"><br/></p><p style=\\\"position: absolute; width: 1px; " +
                "height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 49px;\\\">测试&lt;script&gt;" +
                "alert(11234)&lt;/script&gt;</p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: " +
                "hidden; left: -1000px; white-space: nowrap; top: 49px;\\\"><br/></p><p style=\\\"position: absolute; " +
                "width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 54px;\\\">测试&lt;" +
                "script&gt;alert(11234)&lt;/script&gt;</p><p style=\\\"position: absolute; width: 1px; height: 1px; " +
                "overflow: hidden; left: -1000px; white-space: nowrap; top: 54px;\\\"><br/></p><p style=\\\"position: " +
                "absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 59px;" +
                "\\\">测试&lt;script&gt;alert(11234)&lt;/script&gt;v</p><p style=\\\"position: absolute; width: 1px; " +
                "height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 59px;\\\"><br/></p>\"," +
                "\"cover\":\"\",\"isPermit\":\"\",\"keyword\":\"\",\"stickStatus\":0,\"startDate\":\"\"," +
                "\"endDate\":\"\",\"deptId\":\"\",\"roleId\":\"\",\"userId\":\"education\",\"promulgator\":\"教超管\"," +
                "\"publishStatus\":0,\"auditStatus\":0,\"fsetId\":\"\",\"flowId\":\"\"},\"articleAuthList\":[]}";
        System.out.println(XssUtil.html2Text(ss));
        // 特殊字符匹配
        Matcher scriptMatcher = Pattern.compile(REGEX_SPECIAL_CHARS, Pattern.CASE_INSENSITIVE).matcher(input);
        if (scriptMatcher.find()) {
            System.out.println("REGEX_SPECIAL_CHARS XSS");
            System.out.println(scriptMatcher.group(0));
            System.out.println(input);
        }
    }
}
package com.XXX.common.wrapper;

import com.XXX.common.utils.XssUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;


/**
 * HttpServletRequest包装器,用于防御XSS攻击
 * @since 2015 4 23
 * @author BENSON
 * @version 1.1
 */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final String body;

    protected static Logger logger = LoggerFactory.getLogger(XssHttpServletRequestWrapper.class);

    public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream,Charset.forName("UTF-8")));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = XssUtil.html2Text(stringBuilder.toString());
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
        ServletInputStream servletInputStream = new ServletInputStream() {
            public boolean isFinished() {
                return false;
            }
            public boolean isReady() {
                return false;
            }
            public void setReadListener(ReadListener readListener) {}
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;

    }
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream(),"UTF-8"));
    }
    public String getBody() {
        return this.body;
    }

    /**
     * 覆盖getHeader方法,将参数名和参数值都做XSS过滤。<br/>
     * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
     * getHeaderNames 也可能需要覆盖
     */
     @Override
    public String getHeader(String name) {
        String value = super.getHeader(name);  
        value = XssUtil.stripXSS(value);
        return value;
    }


    @Override
    public String[] getParameterValues(String parameter) {
        String[] values = super.getParameterValues(parameter);
        // 空处理
        if (null == values) {
            return null;
        }

        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = XssUtil.stripXSS(values[i]);
        }
        
        return encodedValues;
    }
    
    /**
     * 覆盖getParameter方法,将参数名和参数值都做XSS过滤。<br/> 
     */
    @Override
    public String getParameter(String name) {  
        String value = super.getParameter(name);
        value = XssUtil.stripXSS(value);
        return value;  
    }  
}

package com.XXX.common.utils;

import java.util.regex.Pattern;

/**
 * html标签工具类
 * @author kermit
 *
 */
public class HtmlStringUtil {
    /**
     * 过滤html的标签
     * @param inputString
     * @return
     */
    public static String Html2Text(String inputString) {
        String htmlStr = inputString; // 含html标签的字符串
        String textStr = "";
        Pattern p_script;
        java.util.regex.Matcher m_script;
        Pattern p_style;
        java.util.regex.Matcher m_style;
        Pattern p_html;
        java.util.regex.Matcher m_html;
        Pattern p_space;
        java.util.regex.Matcher m_space;

        try {
            String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
//          String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
//                                                                                                       }
            String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
//          String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
                                                                                                    // }
            String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
            
            String regEx_space = "&nbsp;";

            p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤script标签

            p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
            m_style = p_style.matcher(htmlStr);
            htmlStr = m_style.replaceAll(""); // 过滤style标签

            p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
            m_html = p_html.matcher(htmlStr);
            htmlStr = m_html.replaceAll(""); // 过滤html标签
            
            p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE);
            m_space = p_space.matcher(htmlStr);
            htmlStr = m_space.replaceAll(" ");//过滤&nbsp;标签

            textStr = htmlStr;

        } catch (Exception e) {
            System.err.println("Html2Text: " + e.getMessage());
        }

        return textStr;// 返回文本字符串
    }
}

package com.XXX.common.utils;

import java.util.ArrayList;
import java.util.List;

/**
 * SQL关键字缓存类(用于XXS攻击的检测.)
 * @since 2015 6 14
 * @author BENSON
 * @version 1.1
 */
public class SqlKeysCache {

    private static List<String> sqlKeysList = new ArrayList<String>(7) {
        {
            add(" insert ");
            add(" update ");
            add(" delete ");
            add(" and ");   
            add(" or ");    
            add(" order "); 
            add(" by "); 
            
            add(" case ");
            add(" when ");
            add(" then ");
            add(" else ");
        }
    };

//  public static void init() {
//      sqlKeysList = new ArrayList<String>(7);
//      sqlKeysList.add(" insert ");
//      sqlKeysList.add(" update ");
//      sqlKeysList.add(" delete ");
//      sqlKeysList.add(" and ");
//      sqlKeysList.add(" or ");
//      sqlKeysList.add(" order ");
//      sqlKeysList.add(" by ");
//  }

    /**
     * 获取SQL关键字集合
     * @return
     */
    public static List<String> getSqlKeysList() {
        return sqlKeysList;
    }
    
}

上一篇下一篇

猜你喜欢

热点阅读