跨站脚本 XSS<一:防御方法>

1. 过滤特殊字符

避免XSS的方法之一主要是将用户所提供的内容进行过滤,许多语言都有提供对HTML的过滤:

 

 

2. 应用<java语言>

  在web应用中主要是通过在过滤器中将可能造成攻击的字符进行转义,转义之后存到数据库中,从而避免攻击。

  

   XSSFilter.java过滤器配置

package util.web;

import *;

/**
 * xss过滤器和CSRF过滤
 * 防 XSS 之全角替换半角
 * 防CSRF之HTTP 头设置 Referer过滤  
 * */
public class XSSFilter implements Filter {
    @Override
    public void init(FilterConfig filterconfig) throws ServletException {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest servletrequest,ServletResponse servletresponse, FilterChain filterchain)throws IOException, ServletException {        
        // 防 XSS
        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest)servletrequest);//***包装转换请求中的可能攻击的字段
        filterchain.doFilter(xssRequest, httpResp);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }
}

 

 

  XssHttpServletRequestWrapper .java 主要重写getParameter()和getParameterValues()方法,对获取的值进行转义。

package util.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
 * 针对普通字符串进行过滤转义
 * 本质是把符号额度半角变成全角
 * 这样JS就执行不了了*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    HttpServletRequest orgRequest = null; 
       
    public XssHttpServletRequestWrapper(HttpServletRequest request) { 
        super(request); 
        orgRequest = request; 
    } 
   
    /**
     * 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/>
     * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
     * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
     */ 
    @Override 
    public String getParameter(String name) { 
        String value = super.getParameter(xssEncode(name)); 
        if(value != null) { 
            value = xssEncode(value); 
        } 
        return value; 
    } 
   @Override 
  public String[] getParameterValues(String name) {
        String[]parameters=super.getParameterValues(name);
        if (parameters==null||parameters.length == 0) {
            return null;
        }
        for (int i = 0; i < parameters.length; i++) {
            parameters[i] = xssEncode(parameters[i]);
        }
        return parameters;
    }
    /**
     * 覆盖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; 
        } 
        StringBuilder sb = new StringBuilder(s.length() + 16); 
        for(int i = 0; i < s.length(); i++) { 
            char c = s.charAt(i); 
            switch(c) { 
            case'>': 
                sb.append(">");// 转义大于号  
                break; 
            case'<': 
                sb.append("<");// 转义小于号  
                break; 
            case'\'': 
                sb.append("'");// 转义单引号  
                break; 
            /*case'\"': 
                sb.append(""");// 转义双引号  ;***先注释掉,会影响json的转化
                break; */
            case'&': 
                sb.append("&");// 转义&  
                break; 
            default: 
                sb.append(c); 
                break; 
            } 
        } 
        return sb.toString(); 
    } 
   
    /**
     * 获取最原始的request
     * 
     * @return
     */ 
    public HttpServletRequest getOrgRequest() { 
        return orgRequest; 
    } 
   
    /**
     * 获取最原始的request的静态方法
     * 
     * @return
     */ 
    public static HttpServletRequest getOrgRequest(HttpServletRequest req) { 
        if(req instanceof XssHttpServletRequestWrapper) { 
            return((XssHttpServletRequestWrapper) req).getOrgRequest(); 
        } 
   
        return req; 
    } 
}

 

 

3.结论

  以上的方法中只是提供的一个简单和原理性的实现,在getParameter()和getParameterValues()方法中调用 xssEncode() 方法转义。

 

附:

  通过Apache的一个xss转义项目也可以实现:https://code.google.com/archive/p/xssprotect/wikis/HowTouse.wiki

 

 

 

 参考资料:

  1.http://itindex.net/detail/46431-xssproject-java-web

  2.http://liuzidong.iteye.com/blog/1744023

 

posted @ 2016-12-23 18:11  孙猴子  阅读(713)  评论(0编辑  收藏  举报