美文网首页
防止XSS攻击

防止XSS攻击

作者: Lymen_lcm | 来源:发表于2018-10-30 11:22 被阅读0次

    关于什么是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;
        }
        
    }
    
    

    相关文章

      网友评论

          本文标题:防止XSS攻击

          本文链接:https://www.haomeiwen.com/subject/ounwtqtx.html