SpringMVC防止XSS攻擊
阿新 • • 發佈:2019-01-09
XSS全稱為跨站指令碼攻擊 , 具體見百度百科
最常見的是用Filter來預防 , 就是建立一個新的httpRequest類XsslHttpServletRequestWrapper,然後重寫一些get方法(獲取引數時對引數進行XSS判斷預防).
1 . 在web.xml中新增Filter
<filter> <filter-name>XssFilter</filter-name> <filter-class>com.xbz.filter.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>XssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2 . 編寫XssFilter類
package com.xbz.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class XssFilter implements Filter{ FilterConfig fc = null; public void destroy() { fc = null; } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc) throws IOException, ServletException { fc.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest)req), resp); } public void init(FilterConfig fc) throws ServletException { this.fc = fc; } }
3 . 編寫XssHttpServletRequestWrapper類
package com.xbz.filter; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } public String[] getParameterValues(String parameter) { String[] values = super.getParameterValues(parameter); if (values == null) { return null; } int count = values.length; String[] encodedValues = new String[count]; for (int i = 0; i < count; i++) { encodedValues[i] = cleanXSS(values[i]); } return encodedValues; } public Map<String, String[]> getParameterMap() { Map<String, String[]> map = super.getParameterMap(); Map<String, String[]> encodedMap = new HashMap<String, String[]>(); encodedMap.putAll(map); for (Map.Entry<String, String[]> entry : encodedMap.entrySet()) { String[] value = entry.getValue(); String[] encodedValues = new String[value.length]; for (int i = 0; i < value.length; i++) { encodedValues[i] = cleanXSS(value[i]); } encodedMap.put(entry.getKey(), encodedValues); } return encodedMap; } public String getParameter(String parameter) { String value = super.getParameter(parameter); if (value == null) { return null; } return cleanXSS(value); } public String getHeader(String name) { String value = super.getHeader(name); if (value == null) return null; return cleanXSS(value); } private String cleanXSS(String value) { if (value != null) { // Avoid null characters 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(""); } return filter(value); } /** * 過濾特殊字元 */ public static String filter(String value) { if (value == null) { return null; } StringBuffer result = new StringBuffer(value.length()); for (int i = 0; i < value.length(); ++i) { switch (value.charAt(i)) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '"': result.append("\""); break; case '\'': result.append("'"); break; case '%': result.append("%"); break; case ';': result.append(";"); break; case '(': result.append("("); break; case ')': result.append(")"); break; case '&': result.append("&"); break; case '+': result.append("+"); break; default: result.append(value.charAt(i)); break; } } return result.toString(); } }