在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");
response.setContentType("text/html;charset=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();
}
/**
- 获取指定参数名的值,如果有重复的参数名,则返回第一个的值
*
- @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、xml、sql
- 解码:StringEscapeUtils.unescapeXml(value)
StringEscapeUtils.escapeJavaScript(value) StringEscapeUtils.escapeSql(value) */ private String escapeXSS(String value){
if (value == null || value.isEmpty()) { return value; } value = StringEscapeUtils.escapeXml(value); value = StringEscapeUtils.escapeJavaScript(value); value = StringEscapeUtils.escapeSql(value); value = value.replaceAll("<", "<"); value = value.replaceAll(">", ">"); value = value.replaceAll("'", "'"); value = value.replaceAll(";", "﹔"); value = value.replaceAll("&", "&"); value = value.replaceAll("%", "﹪"); value = value.replaceAll("#", "#"); value = value.replaceAll("sleep", " "); value = value.replaceAll("select", "select");// "c"→"ᴄ"
value = value.replaceAll("prompt", " ");
value = value.replaceAll("truncate", "trunᴄate");// "c"→"ᴄ"
value = value.replaceAll("exec", "exeᴄ");// "c"→"ᴄ"
value = value.replaceAll("join", "jᴏin");// "o"→"ᴏ"
value = value.replaceAll("union", "uniᴏn");// "o"→"ᴏ"
value = value.replaceAll("drop", "drᴏp");// "o"→"ᴏ"
value = value.replaceAll("count", "cᴏunt");// "o"→"ᴏ"
value = value.replaceAll("insert", "ins℮rt");// "e"→"℮"
value = value.replaceAll("update", "updat℮");// "e"→"℮"
value = value.replaceAll("delete", "delet℮");// "e"→"℮"
value = value.replaceAll("script", "sᴄript");// "c"→"ᴄ"
value = value.replaceAll("cookie", "cᴏᴏkie");// "o"→"ᴏ"
value = value.replaceAll("iframe", "ifram℮");// "e"→"℮"
value = value.replaceAll("onmouseover", "onmouseov℮r");// "e"→"℮"
value = value.replaceAll("onmousemove", "onmousemov℮");// "e"→"℮"*/
return value;
}
}
第三步:配置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>true</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前,顺便不对可能会出现不生效的情况。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。