在 JAVA 开发工程中难免会呈现 XSS 和 SQL 注入破绽,这些问题的产生都是因为 url 中带有 js、html、特殊字符坑骗服务器达到申请数据。解决的思路是把传到后端的参数进行本义解决,从而防止这些问题的产生。
第一步:自定义 filter 过滤器.
public class XSSFilter extends OncePerRequestFilter {
private String exclude = null; // 不须要过滤的门路汇合
private Pattern pattern = null; // 匹配不须要过滤门路的正则表达式
public void setExclude(String exclude) {
this.exclude = exclude;
pattern = Pattern.compile(getRegStr(exclude));
}
/**
- XSS 过滤
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {String requestURI = request.getRequestURI();
request.setCharacterEncoding("UTF-8");// 设置字符编码
response.setCharacterEncoding("UTF-8");
if(StringUtils.isNotBlank(requestURI))
requestURI = requestURI.replace(request.getContextPath(),"");
if(pattern.matcher(requestURI).matches())
filterChain.doFilter(request, response);
else{EscapeScriptwrapper escapeScriptwrapper = new EscapeScriptwrapper(request);
filterChain.doFilter(escapeScriptwrapper, response);
}
}
/**
- 不须要过滤得门路汇合的字符串格式化成一系列的正则规定
- @param str 不须要过滤的门路汇合
- @return 正则表达式规定
- */
private String getRegStr(String str){
if(StringUtils.isNotBlank(str)){String[] excludes = str.split(";"); // 以分号进行宰割
int length = excludes.length;
for(int i=0;i<length;i++){String tmpExclude = excludes[i];
// 对点、反斜杠和星号进行本义
tmpExclude = tmpExclude.replace(“”, “”).replace(“.”, “.”).replace(““, “.“);
tmpExclude = "^" + tmpExclude + "$";
excludes[i] = tmpExclude;
}
return StringUtils.join(excludes, "|");
}
return str;
}
}
第二步:进行本义
本义规定能够自定义实现,通过正则表白或者本义符都能实现,也可通过 StringEscapeUtils 实现 jar 办法提供的过滤规定,具体实现过程能够上官网观看文档阐明。
public class EscapeScriptwrapper extends HttpServletRequestWrapper {
private Map<String, String[]> parameterMap; // 所有参数的 Map 汇合
public EscapeScriptwrapper(HttpServletRequest request) {
super(request);
parameterMap = request.getParameterMap();}
/**
- 获取所有参数名
- @return 返回所有参数名
- */
@Override
public Enumeration<String> getParameterNames() {
Vector<String> vector = new Vector<String>(parameterMap.keySet());
return vector.elements();}
/**
- 获取指定参数名的值,如果有反复的参数名,则返回第一个的值
- 接管个别变量,如 text 类型
*
- @param name 指定参数名
- @return 指定参数名的值
- */
@Override
public String getParameter(String name) {
String[] results = parameterMap.get(name);
if(results == null || results.length <= 0)
return null;
else{return escapeXSS(results[0]);
}
}
/**
- 获取指定参数名的所有值的数组,如:checkbox 的所有数据
- 接管数组变量,如 checkobx 类型
- */
@Override
public String[] getParameterValues(String name) {
String[] results = parameterMap.get(name);
if(results == null || results.length <= 0)
return null;
else{
int length = results.length;
for(int i=0;i<length;i++){results[i] = escapeXSS(results[i]);
}
return results;
}
}
/**
- 过滤字符串中的 js 脚本
- 解码:StringEscapeUtils.unescapeXml(escapedStr)
-
*/ private String escapeXSS(String str){
str = StringEscapeUtils.escapeXml(str); Pattern tmpPattern = Pattern.compile("[sS][cC][rR][iI][pP][tT]"); Matcher tmpMatcher = tmpPattern.matcher(str); if(tmpMatcher.find()){str = tmpMatcher.replaceAll(tmpMatcher.group(0) + ""); } return str;
}
}
第三步:配置 web.xml 文件
<!– 解决 xss & sql 破绽 –>
<filter>
<filter-name>xss</filter-name>
<filter-class>cn.com.gzqinghui.sysmgr.xss.XSSFilter</filter-class>
<init-param>
<param-name>exclude</param-name>
<param-value>/;/scripts/*;/styles/*;/p_w_picpaths/*;/prompt/*;/prompt(1)/*;/iframe/*;/frame/*,/on/*;/quot/*;</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>xss</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
注:配置程序必须在监听器 listener 后,servlet 前,顺便不对可能会呈现不失效的状况。