预防XSS攻击,(参数/响应值)特殊字符过滤

来源:互联网 发布:科创论坛 知乎 编辑:程序博客网 时间:2024/05/29 04:07

一、什么是XSS攻击 
XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。

二、XSS漏洞的危害 
(1)网络钓鱼,包括盗取各类用户账号; 
(2)窃取用户cookies资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作; 
(3)劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等; 
(4)强制弹出广告页面、刷流量等; 
(5)网页挂马; 
(6)进行恶意操作,例如任意篡改页面信息、删除文章等; 
(7)进行大量的客户端攻击,如DDoS攻击; 
(8)获取客户端信息,例如用户的浏览历史、真实IP、开放端口等; 
(9)控制受害者机器向其他网站发起攻击; 
(10)结合其他漏洞,如CSRF漏洞,实施进一步作恶; 
(11)提升用户权限,包括进一步渗透网站; 
(12)传播跨站脚本蠕虫等; 
……

三、如何编写代码来避免 
如下代码可以避免XSS注入,但是作者因知识面有限,故不能保证100%能完全将XSS攻击者拒之门外,还需大家根据实际情况进行优化和改进。 
既然我们通过代码来解决问题,就尽可能的不涉及开发人员的对原有代码修改,所以我们增加过滤器来拦截处理,本文原有框架使用springmvc。 
1、IllegalCharacterFilter.java

package com.lenovo.common.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;/** * 非法字符过滤器,用来处理request.getParamater中的非法字符。如<script>alert('123');</script> *  * @author 单红宇(365384722) * @myblog http://blog.csdn.net/catoop/ * @create 2015年9月18日 */public class IllegalCharacterFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest req, ServletResponse res,            FilterChain chain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest)req;        request = new MHttpServletRequest(request);        chain.doFilter(request, res);    }    @Override    public void destroy() {    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

2、MHttpServletRequest.java

package com.lenovo.common.filter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import com.lenovo.common.utils.XssShieldUtil;/** * 参数特殊字符过滤 * * @author   单红宇(365384722) * @myblog  http://blog.csdn.net/catoop/ * @create    2015年9月18日 */public class MHttpServletRequest extends HttpServletRequestWrapper {    public MHttpServletRequest(HttpServletRequest request) {        super(request);    }    @Override    public String getParameter(String name) {        // 返回值之前 先进行过滤        return XssShieldUtil.stripXss(super.getParameter(XssShieldUtil.stripXss(name)));    }    @Override    public String[] getParameterValues(String name) {        // 返回值之前 先进行过滤        String[] values = super.getParameterValues(XssShieldUtil.stripXss(name));        if(values != null){            for (int i = 0; i < values.length; i++) {                values[i] = XssShieldUtil.stripXss(values[i]);            }        }        return values;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

3、XssShieldUtil.java

package com.lenovo.common.utils;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.apache.commons.lang.StringUtils;/** * 处理非法字符 * * @author   单红宇(365384722) * @myblog  http://blog.csdn.net/catoop/ * @create    2015年9月18日 */public class XssShieldUtil {    private static List<Pattern> patterns = null;    private static List<Object[]> getXssPatternList() {        List<Object[]> ret = new ArrayList<Object[]>();        ret.add(new Object[]{"<(no)?script[^>]*>.*?</(no)?script>", Pattern.CASE_INSENSITIVE});        ret.add(new Object[]{"eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});        ret.add(new Object[]{"expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});        ret.add(new Object[]{"(javascript:|vbscript:|view-source:)*", Pattern.CASE_INSENSITIVE});        ret.add(new Object[]{"<(\"[^\"]*\"|\'[^\']*\'|[^\'\">])*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});        ret.add(new Object[]{"(window\\.location|window\\.|\\.location|document\\.cookie|document\\.|alert\\(.*?\\)|window\\.open\\()*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});        ret.add(new Object[]{"<+\\s*\\w*\\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\\s*=+", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});        return ret;    }    private static List<Pattern> getPatterns() {        if (patterns == null) {            List<Pattern> list = new ArrayList<Pattern>();            String regex = null;            Integer flag = null;            int arrLength = 0;            for(Object[] arr : getXssPatternList()) {                arrLength = arr.length;                for(int i = 0; i < arrLength; i++) {                    regex = (String)arr[0];                    flag = (Integer)arr[1];                    list.add(Pattern.compile(regex, flag));                }            }            patterns = list;        }        return patterns;    }    public static String stripXss(String value) {        if(StringUtils.isNotBlank(value)) {            Matcher matcher = null;            for(Pattern pattern : getPatterns()) {                matcher = pattern.matcher(value);                // 匹配                if(matcher.find()) {                    // 删除相关字符串                    value = matcher.replaceAll("");                }            }            value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");        }//      if (LOG.isDebugEnabled())//          LOG.debug("strip value: " + value);        return value;    }    public static void main(String[] args) {        String value = null;        value = XssShieldUtil.stripXss("<script language=text/javascript>alert(document.cookie);</script>");        System.out.println("type-1: '" + value + "'");        value = XssShieldUtil.stripXss("<script src='' onerror='alert(document.cookie)'></script>");        System.out.println("type-2: '" + value + "'");        value = XssShieldUtil.stripXss("</script>");        System.out.println("type-3: '" + value + "'");        value = XssShieldUtil.stripXss(" eval(abc);");        System.out.println("type-4: '" + value + "'");        value = XssShieldUtil.stripXss(" expression(abc);");        System.out.println("type-5: '" + value + "'");        value = XssShieldUtil.stripXss("<img src='' onerror='alert(document.cookie);'></img>");        System.out.println("type-6: '" + value + "'");        value = XssShieldUtil.stripXss("<img src='' onerror='alert(document.cookie);'/>");        System.out.println("type-7: '" + value + "'");        value = XssShieldUtil.stripXss("<img src='' onerror='alert(document.cookie);'>");        System.out.println("type-8: '" + value + "'");        value = XssShieldUtil.stripXss("<script language=text/javascript>alert(document.cookie);");        System.out.println("type-9: '" + value + "'");        value = XssShieldUtil.stripXss("<script>window.location='url'");        System.out.println("type-10: '" + value + "'");        value = XssShieldUtil.stripXss(" onload='alert(\"abc\");");        System.out.println("type-11: '" + value + "'");        value = XssShieldUtil.stripXss("<img src=x<!--'<\"-->>");        System.out.println("type-12: '" + value + "'");        value = XssShieldUtil.stripXss("<=img onstop=");        System.out.println("type-13: '" + value + "'");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128

4、web.xml 配置

    <!-- 非法参数过滤器 -->    <filter>        <filter-name>IllegalCharacterFilter</filter-name>        <filter-class>com.lenovo.common.filter.IllegalCharacterFilter</filter-class>    </filter>    <filter-mapping>        <filter-name>IllegalCharacterFilter</filter-name>        <url-pattern>*.do</url-pattern>    </filter-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

本文方法针对非Struts2框架,如果在Struts2中解决Xss问题,可以参考:https://yq.aliyun.com/articles/7126

原创粉丝点击