xss攻击过滤

package com.hnbits.application.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.hnbits.easyjava.common.util.MsgUtil;
import com.hnbits.easyjava.common.util.StringUtil;

import cn.hutool.core.collection.CollUtil;

@WebFilter(filterName="xssFilter", urlPatterns="/*")
public class XssFilter implements Filter{

private static Pattern[] patterns = new Pattern[]{
// Script fragments
Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE),
// src='...'
Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// lonely script tags
Pattern.compile("</script>", Pattern.CASE_INSENSITIVE),
Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// eval(...)
Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// expression(...)
Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// javascript:...
Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE),
// vbscript:...
Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE),
// 空格英文单双引号
Pattern.compile("[\\s\'\"]+", Pattern.CASE_INSENSITIVE),
// onload(...)=...
Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
// alert
Pattern.compile("alert(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile("<", Pattern.MULTILINE | Pattern.DOTALL),
Pattern.compile(">", Pattern.MULTILINE | Pattern.DOTALL),
//Checks any html tags i.e. <script, <embed, <object etc.
Pattern.compile("(<(script|iframe|embed|frame|frameset|object|img|applet|body|html|style|layer|link|ilayer|meta|bgsound))")
};

// endsWith(exclude),放行静态资源
public List<String> excludes = Arrays.asList("/login", "/logout", ".html", ".js", ".gif", ".jpg", ".png", ".css",
".ico", ".woff2", ".woff", ".tt", ".ttf");

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
if (handleExcludeURL(req)) {
chain.doFilter(request, response);
return;
}
// 页面是否忽略。
// 检测是否有XSS攻击。
boolean hasXss = checkXss(req);
if (hasXss) {
// response.setContentType("text/html;charset=utf-8");
// PrintWriter out = null;
// try {
// out = response.getWriter();
// out.write(
// JSONObject.toJSONString(MsgUtil.getOutMsg(false, "检测到提交内容含Xss攻击代码以被拦截,您已被记录!", null)));
// // 强制将缓冲区中的数据发送出去,不必等到缓冲区满
// out.flush();
// } catch (IOException e) {
// e.printStackTrace();
// } finally {
// if (out != null) {
// out.close();
// }
// }
request.getRequestDispatcher("/page/jsp/errors/xsserror.jsp").forward(request, response);
} else {
chain.doFilter(request, response);
}

}

@Override
public void destroy() {
// TODO Auto-generated method stub

}

private boolean handleExcludeURL(HttpServletRequest request) {
if (CollectionUtils.isEmpty(excludes)) {
return false;
}

String path = request.getServletPath();
if (path == null) {
return false;
}

return excludes.stream().anyMatch(method -> path.endsWith(method) || path.matches(method));
}

/**
* 判断输入是否有XSS注入问题。
*
* @param request
* @return
*/
private boolean checkXss(HttpServletRequest request) {
Enumeration<?> params = request.getParameterNames();
while (params.hasMoreElements()) {
String key = params.nextElement().toString();
String[] vals = request.getParameterValues(key);
String val = CollUtil.join(Arrays.asList(vals), "");
if (!StringUtil.isEmpty(val)){
for (Pattern scriptPattern : patterns) {
Matcher matcher = scriptPattern.matcher(val);
if (matcher.find()) {
return true;
}
}
}
}
return false;
}

}

posted @ 2021-09-13 22:34  看看反馈  阅读(247)  评论(0)    收藏  举报