跨站點指令碼編制(好多部落格說寫的過濾器親測都是假的,都拿不到引數)
阿新 • • 發佈:2018-12-29
為什麼說別人的都是有問題的呢,看起來沒問題,實際上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 expression
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(...) expressions
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid expression(...) expressions
scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid javascript:... expressions
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid vbscript:... expressions
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid onload= expressions
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;
}