1. 程式人生 > >跨站點指令碼編制(好多部落格說寫的過濾器親測都是假的,都拿不到引數)

跨站點指令碼編制(好多部落格說寫的過濾器親測都是假的,都拿不到引數)

為什麼說別人的都是有問題的呢,看起來沒問題,實際上request獲取的getParameterMap拿到的Map是鎖定的,不能修改,

 

如何修改拿到的Map呢,需要引入tomcat裡的catalina.jar

參考https://blog.csdn.net/darkness_j/article/details/6325245

如下:親測可用

最後value = HtmlUtils.htmlEscape(value); 這個方法要慎用,如果頁面傳json資料到後臺,會把符號都轉碼,導致後臺解析json報錯,可以去掉這個

<filter>
        <filter-name>pramsFilter</filter-name>
        <filter-class>com.str.util.filter.PramsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>pramsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

過濾器:

package com.str.util.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.filter.OncePerRequestFilter;

public class PramsFilter extends OncePerRequestFilter {
	 
		@Override
		protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
				throws ServletException, IOException {
			chain.doFilter(new ParameterRequestWrapper((HttpServletRequest)request), response);
		}

}

ParameterRequestWrapper類

package com.str.util.filter;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.catalina.util.ParameterMap;

import com.five.util.CommUtil;

/**
 * 重寫 HttpServletRequestWrapper 處理json報文請求
 * 
 * @author zhaoheng
 *
 */
public class ParameterRequestWrapper extends HttpServletRequestWrapper  {
	
	public ParameterRequestWrapper(HttpServletRequest request) {
		super(request);
		// TODO Auto-generated constructor stub
	}


	@Override
	public String getParameter(String name) {
		// 返回值之前 先進行過濾
		return CommUtil.cleanPram(super.getParameter(name));
	}

	@Override
	public String[] getParameterValues(String name) {
		// 返回值之前 先進行過濾
		String[] values = super.getParameterValues(name);
		if (values == null) {
			return null;
		}
		for (int i = 0; i < values.length; i++) {
			values[i] = CommUtil.cleanPram(values[i]);
		}

		return values;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Map getParameterMap() {
		ParameterMap keys=(ParameterMap)super.getParameterMap(); 
		Method method;
		try {
			method = keys.getClass().getMethod( "setLocked" , new  Class[]{ boolean . class });
			method.invoke(keys,new  Object[]{ new  Boolean( false )});  
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		Set set = keys.entrySet();
		Iterator iters = set.iterator();
		while (iters.hasNext()) {
			Object key =iters.next();
			Map.Entry<Object, Object> sEntry=(Map.Entry<Object, Object>)key;
			String[] value = (String[])sEntry.getValue();
			if(null!=value) {
				for (int i = 0; i < value.length; i++) {
					value[i]=CommUtil.cleanPram(value[i]);
				}
				sEntry.setValue(value);
			}
		}
		return keys;
	}
}

CommUtil類主要方法:

import org.apache.commons.lang.StringUtils;
import org.springframework.web.util.HtmlUtils;

 public static String cleanPram(String pram  ) {
    	if (null!=pram) {
    		pram=xssClean_4(pram);
    		pram=xssClean(pram);
    		pram=xssClean_error(pram);
    	}
    	return pram;
    }
    
    
    private static String xssClean_4(String value) {//介面會報錯
        value = HtmlUtils.htmlEscape(value);
        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
        value = value.replaceAll("'", "& #39;");
        value = value.replaceAll("eval\\((.*)\\)", "");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        value = value.replaceAll("script", "");
        return value;
    }
    /**
     * 將容易引起xss漏洞的半形字元直接替換成全形字元
     *  清除惡意的XSS指令碼
     * @param s
     * @return
     */ 
    private static String xssClean(String value) { 
        if (value == null || value.isEmpty()) { 
            return value; 
        } 
        value = HtmlUtils.htmlEscape(value);
         //對%28 %29 %22轉碼
            value =value.replaceAll("%(?![0-9a-fA-F]{2})", "%25");   
            try {
				value= URLDecoder.decode(value,"UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
        value = value.replaceAll("'", "& #39;");
        value = value.replaceAll("eval\\((.*)\\)", "");
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
        value = value.replaceAll("script", "");
         
        StringBuilder sb = new StringBuilder(value.length() + 16); 
        for (int i = 0; i < value.length(); i++) { 
            char c = value.charAt(i); 
            switch (c) { 
            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(); 
    }
    private static  String xssClean_error(String value) {
        if (value != null) {
            value = value.replaceAll("", "");
            // Avoid anything between script tags
            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Avoid anything in a src="http://www.yihaomen.com/article/java/..." type of e­xpression
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome </script> tag
            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
            value = scriptPattern.matcher(value).replaceAll("");
            // Remove any lonesome <script ...> tag
            scriptPattern = Pattern.compile("<script(.*?)>", 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("");
            scriptPattern = Pattern.compile("alert *\\(((?!([alert\\(|\\)])).)*\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
            value = scriptPattern.matcher(value).replaceAll("");//去除alert()  
             
            value = HtmlUtils.htmlEscape(value);
        }
        return value;
    }