Java编写Filter实现防止XSS攻击

什么是XSS攻击

  • XSS攻击 攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。(摘自百度百科)
  • SQL注入: SQL注入指的是发生在Web应用对后台数据库查询语句处理存在的安全漏洞,简单的说,就是在输入字符串中嵌入SQL指令,在设计程序中忽略了对特殊字符串的检查,这些嵌入的指令便会被误认为正常的SQL指令,在数据库中执行,因此可以对后台数据库进行查看等工作,甚至破快后台数据库造成严重后果。

使用过滤器防止

  • 使用转换过滤或拦截非法请求字符来防止XSS攻击
    **编写防止XSS攻击的XssFilter **
public class XssFilter implements Filter {
 
 
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
			ServletException {
		
			XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
			(HttpServletRequest) request);
			filterChain.doFilter(xssRequest, response);
		
	}
	
	 public void init(FilterConfig conf) throws ServletException { 
		 System.out.println("PreventXSSInject Filter staring..."); 
         System.out.println(); 
	 }
	 
	 public void destroy() { 
         
	 } 
 
}

编写防止SQL注入的SqlInjectFilter

public class SqlInjectFilter implements Filter {
	private static List invalidsql = new ArrayList(); 
    private static String error = "/sqlerrors.jsp"; 
    private static boolean debug = false; 
     
    public void destroy() { 
         
    } 
    public void doFilter(ServletRequest req, ServletResponse res, 
            FilterChain fc) throws IOException, ServletException { 
       //防sql关键字注入
    	if(debug){ 
            System.out.println("prevent sql inject filter works"); 
        } 
        HttpServletRequest request = (HttpServletRequest)req; 
        HttpServletResponse response = (HttpServletResponse)res; 
        Map params = request.getParameterMap(); 
        Set keys = params.keySet(); 
        for(String key : keys){ 
            String value = request.getParameter(key); 
            if(debug){ 
                System.out.println("process params : <"+key+", "+value+">"); 
            } 
            for(String word : invalidsql){ 
                if(word.equalsIgnoreCase(value) || value.contains(word)){ 
                    if(value.contains("<")){ 
                        value = value.replace("<", "<"); 
                    } 
                    if(value.contains(">")){ 
                        value = value.replace(">", ">"); 
                    } 
                    if(value.contains("(")){ 
                    	value = value.replace("(", "("); 
                    }
                    if(value.contains(")")){ 
                    	value = value.replace(")", ")"); 
                    }
                    request.getSession().setAttribute("sqlInjectError", "您输入的参数值  \""+value+"\" 中包含关键字: \""+word+"\""); 
                    response.sendRedirect(request.getContextPath()+error); 
                    return; 
                } 
            } 
        } 
        fc.doFilter(req, res);
    } 
    public void init(FilterConfig conf) throws ServletException { 
        String sql = conf.getInitParameter("invalidsql"); 
        String errorpage = conf.getInitParameter("error"); 
        String de = conf.getInitParameter("debug"); 
        if(errorpage != null){ 
            error = errorpage; 
        } 
        if(sql != null){ 
            //invalidsql = Arrays.asList(sql.split(" ")); 
        	String[] sqlarr = sql.split(" ");
        	for(String sqlword:sqlarr){
        		invalidsql.add(sqlword);
        	}
        	invalidsql.add("<");
            invalidsql.add(">");
            invalidsql.add("(");
            invalidsql.add(")");
        } 
        if(de != null && Boolean.parseBoolean(de)){ 
            debug = true; 
            System.out.println("PreventSQLInject Filter staring..."); 
            System.out.println("print filter details"); 
            System.out.println("invalid words as fllows (split with blank):"); 
            for(String s : invalidsql){ 
                System.out.print(s+" "); 
            } 
            System.out.println(); 
            System.out.println("error page as fllows"); 
            System.out.println(error); 
            System.out.println(); 
        }
    }
}

XSS包装器 XssHttpServletRequestWrapper.java


public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
	HttpServletRequest orgRequest = null;
 
	public XssHttpServletRequestWrapper(HttpServletRequest request) {
		super(request);
		orgRequest = request;
	}
 
	/**
	* 覆盖getParameter方法,将参数名和参数值都做xss过滤。
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖 */ @Override public String getParameter(String name) { String value = super.getParameter(xssEncode(name)); if (value != null) { value = xssEncode(value); } return value; } /** * 覆盖getHeader方法,将参数名和参数值都做xss过滤。
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取
* 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 || "".equals(s)) { 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('“');//全角双引号 break; case '&': sb.append('&');//全角 break; case '\\': sb.append('\');//全角斜线 break; case '#': sb.append('#');//全角井号 break; case '(': sb.append('(');//全角井号 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; } }

最后在web.xml中配置filter


	
	    XssFilter
	    
	        com.megait.jgjz.web.filter.XssFilter
	    
	
	
	    XssFilter
	    /*
	
	
   
     PreventSqlInject 
     com.megait.jgjz.web.filter.SqlInjectFilter 
      
      
         invalidsql 
         select insert delete from update create where union destory drop alter and or like exec count chr mid master truncate char declare ; - ' % | $ % @ " + cr lf , . script document eval 
      
      
      
         error 
         /sqlerrors.jsp 
      
          
      
         debug 
         true 
      
    
    
     PreventSqlInject 
     /* 
   

最后因为脚本注入 则使页面跳转到error.jsp页面


<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 
 <% 
 String path = request.getContextPath(); 
 %> 
  
  
    
   	
     防sql注入系统 
    
    
    
     这个是防sql注入系统,自动过滤您的请求,请更换请求字符
     <%=session.getAttribute("sqlInjectError")%>
    
  

你可能感兴趣的:(web安全)