@Author Jacky Wang,转载请注明出处https://www.jianshu.com/p/8c11901a9778
步骤:
- pom添加maven依赖
- 自定义过滤器Filter拦截请求,并对请求参数进行xss过滤处理
具体实现如下:
1. pom添加依赖
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>8.0.36</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
2. 自定义过滤器Filter,并对请求Request进行xss过滤处理
@SpringBootConfiguration
@WebFilter(filterName = "XssFilter",urlPatterns = {"/*"})
public class XssFilter implements Filter {
/**无需进行xss过滤的uri地址*/
private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("/pay/wxNotify","/pay/alNotify","/pay/gateway")));
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
boolean allowedPath = ALLOWED_PATHS.contains(path);
if(allowedPath) {
chain.doFilter(request, response);
}else {
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
-------------------------------------------------------------------------------------------------
XSSRequestWrapper是Request的包装类,用于修改Request请求,这是拦截器Interceptor所不能做到的:
public class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest request) {
super(request);
}
/**
* 对数组参数进行特殊字符过滤
*/
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = clearXss(values[i]);
}
return encodedValues;
}
/**
* 对参数中特殊字符进行过滤
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) {
return null;
}
return clearXss(value);
}
/**
* 获取attribute,特殊字符过滤
*/
@Override
public Object getAttribute(String name) {
Object value = super.getAttribute(name);
if (value != null && value instanceof String) {
clearXss((String) value);
}
return value;
}
/**
* 对请求头部进行特殊字符过滤
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) {
return null;
}
return clearXss(value);
}
/**
* @Title: clearXss
* @Description: TODO(xss攻击处理)
* @param: @param value
* @param: @return
* @return: String
* @throws
*/
private String clearXss(String value) {
if (StringUtils.isEmpty(value)) {
return value;
}
try {
value = new String(value.getBytes("ISO8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return XssFilterUtil.stripXss(value);
}
}
---------------------------------------------------------------------------------------------
public class XssFilterUtil {
private static List<Pattern> patterns = null;
/*private static List<Object[]> getXssPatternList() {
List<Object[]> ret = new ArrayList<Object[]>();
ret.add(new Object[]{"<(no)?script[^>]*>.*?</(no)?script>", Pattern.CASE_INSENSITIVE});
ret.add(new Object[]{"eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"(javascript:|vbscript:|view-source:)*", Pattern.CASE_INSENSITIVE});
ret.add(new Object[]{"<(\"[^\"]*\"|\'[^\']*\'|[^\'\">])*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"(window\\.location|window\\.|\\.location|document\\.cookie|document\\.|alert\\(.*?\\)|window\\.open\\()*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"<+\\s*\\w*\\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\\s*=+", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
return ret;
}*/
private static List<Object[]> getXssPatternList() {
List<Object[]> ret = new ArrayList<Object[]>();
ret.add(new Object[]{"<(no)?script[^>]*>.*?</(no)?script>", Pattern.CASE_INSENSITIVE});
ret.add(new Object[]{"</script>", Pattern.CASE_INSENSITIVE});
ret.add(new Object[]{"<script(.*?)>",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"(javascript:|vbscript:|view-source:)*", Pattern.CASE_INSENSITIVE});
ret.add(new Object[]{"<(\"[^\"]*\"|\'[^\']*\'|[^\'\">])*>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"(window\\.location|window\\.|\\.location|document\\.cookie|document\\.|alert\\(.*?\\)|window\\.open\\()*", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
ret.add(new Object[]{"<+\\s*\\w*\\s*(oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondblclick|ondeactivate|ondrag|ondragend|ondragenter|ondragleave|ondragover|ondragstart|ondrop|onerror=|onerroupdate|onfilterchange|onfinish|onfocus|onfocusin|onfocusout|onhelp|onkeydown|onkeypress|onkeyup|onlayoutcomplete|onload|onlosecapture|onmousedown|onmouseenter|onmouseleave|onmousemove|onmousout|onmouseover|onmouseup|onmousewheel|onmove|onmoveend|onmovestart|onabort|onactivate|onafterprint|onafterupdate|onbefore|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onblur|onbounce|oncellchange|onchange|onclick|oncontextmenu|onpaste|onpropertychange|onreadystatechange|onreset|onresize|onresizend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onselect|onselectionchange|onselectstart|onstart|onstop|onsubmit|onunload)+\\s*=+", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL});
return ret;
}
private static List<Pattern> getPatterns() {
if (patterns == null) {
List<Pattern> list = new ArrayList<Pattern>();
String regex = null;
Integer flag = null;
int arrLength = 0;
for(Object[] arr : getXssPatternList()) {
arrLength = arr.length;
for(int i = 0; i < arrLength; i++) {
regex = (String)arr[0];
flag = (Integer)arr[1];
list.add(Pattern.compile(regex, flag));
}
}
patterns = list;
}
return patterns;
}
public static String stripXss(String value) {
if(StringUtils.isNotBlank(value)) {
Matcher matcher = null;
for(Pattern pattern : getPatterns()) {
matcher = pattern.matcher(value);
// 匹配
if(matcher.find()) {
// 删除相关字符串
value = matcher.replaceAll("");
}
}
//value = value.replaceAll("<", "<").replaceAll(">", ">");
//删除特殊符号
String specialStr = "%20|=|!=|-|--|;|'|\"|%|#|+|//|/| |\\|<|>|(|)|{|}";
for (String str : specialStr.split("\\|")) {
if(value.indexOf(str) > -1) {
value = value.replaceAll(str, "");
}
}
}
// if (LOG.isDebugEnabled())
// LOG.debug("strip value: " + value);
System.err.println(value);
return value;
}
}
网友评论