一,web.xml 文件添加过滤,要加在登陆验证之前
<!-- 特殊字符过滤验证或转义 -->
<filter>
<filter-name>XSSFilter</filter-name>
<filter-class>com.web.system.filter.XSSFilter</filter-class>
<init-param>
<param-name>validate</param-name>
<param-value>
<![CDATA[
expression|prompt|iframe|frame|SYS.TAB|script|alert|src|href|%|<|>|\\x|%5Cx|\*/|/\*|\> |\<|\‘|\“|\\|\/|\(|\)
]]>
</param-value>
</init-param>
<init-param>
<param-name>ignoreurl</param-name>
<param-value></param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>XSSFilter</filter-name>
<url-pattern>/loginCheck</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
二,添加自定义拦截 XSSFilter.java
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Map;
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.http.HttpServletRequest;
import org.apache.log4j.Logger;
/**
* <p>
* Title: XSSFilter
* </p>
* <p>
* Description: XSS防御过滤器
* </p>
*
* @author msCall
* @date 2018-9-12
*/
public class XSSFilter implements Filter {
private static Logger logger = Logger.getLogger(XSSFilter.class);
private FilterConfig config = null;
private static String validate = "--|'";
private String ignoreurl = "";
@Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
validate = config.getInitParameter("validate");
ignoreurl = config.getInitParameter("ignoreurl");
}
@Override
public void destroy() {
config = null;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
XSSHttpServletRequestWraper wrapper = new XSSHttpServletRequestWraper((HttpServletRequest) request);
String comKey = null;
String comStr = null;
String[] arrStr = null;
String checkRs = null;
String method = ((HttpServletRequest) wrapper).getMethod();
/**
* 拦截get请求
*/
if (method != null && "get".compareToIgnoreCase(method) == 0) {
// String requestUrl = ((HttpServletRequest) wrapper).getRequestURL().toString().toLowerCase();
// if (!"".equals(((HttpServletRequest) wrapper).getQueryString())
// && null != ((HttpServletRequest) wrapper).getQueryString()) {
// requestUrl = ((HttpServletRequest) wrapper).getQueryString().toLowerCase();
// } else {
// chain.doFilter(wrapper, response);
// return;
// }
// /**
// * 如果是白名单就直接跳过
// */
// if (isIgnoreUrl(((HttpServletRequest) wrapper).getRequestURL().toString().toLowerCase())) {
// chain.doFilter(wrapper, response);
// return;
// }
//
// try {
// requestUrl = java.net.URLDecoder.decode(requestUrl, "UTF-8");
// } catch (Exception e) {
// e.printStackTrace();
// }
// checkRs = dataAutoCheck(requestUrl);
// if (!"RSRIGHT".equals(checkRs)) {
// wrapper.getRequestDispatcher("/pages/err_str_limite.jsp").forward(request, response);
// return;
// }
chain.doFilter(wrapper, response);
return;
}
/**
* 拦截POST请求
*/
else {
checkRs = null;
/**
* 如果是白名单就直接跳过
*/
if (isIgnoreUrl(((HttpServletRequest) wrapper).getRequestURL().toString().toLowerCase())) {
chain.doFilter(wrapper, response);
return;
}
Map allFormDateMap = (Map) wrapper.getParameterMap(); // 获取表单提交过来的数据
for (Iterator i = allFormDateMap.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
Object ob = (Object) entry.getValue();
Object key = (Object) entry.getKey();
/**
* 验证表单的key
*/
if (key instanceof String) {
comKey = (String) key;
if(comKey.equals("content"))continue; //如果是公告管理的内容字段content,则跳过过滤
checkRs = dataAutoCheck(comKey);
}
/**
* 验证表单的value
*/
if (ob != null && ob instanceof String) {
comStr = (String) ob;
checkRs = dataAutoCheck(comStr);
} else if (ob != null && ob instanceof String[]) {
arrStr = (String[]) ob;
for (int j = 0; j < arrStr.length; j++) {
comStr = arrStr[j];
checkRs = dataAutoCheck(comStr);
if (!"RSRIGHT".equals(checkRs))
break;
}
}
if (!"RSRIGHT".equals(checkRs)) {
wrapper.getRequestDispatcher("/err_str_limite.jsp.jsp").forward(request,
response);
// response.setCharacterEncoding("utf-8");
// PrintWriter out = response.getWriter();
// Map<String, String> map = new HashMap<>();
// map.put("errtype", "xss");
// map.put("errinfo", "输入信息中包含非法数据!");
// out.print(JSON.toJSONString(map));
// out.close();
return;
}
}
}
chain.doFilter(wrapper, response);
}
private boolean isIgnoreUrl(String url) {
String param[] = ignoreurl.split(",");
for (int i = 0; i < param.length; i++) {
if (url.indexOf(String.valueOf(param[i]).toLowerCase()) > 0) {
return true;
}
}
return false;
}
/**
*
* @description 根据过滤规则过滤XSS攻击字符
* @author msCall
* @date 2018-9-12
* @param str 表单提交的值
* @return 验证结果
*/
public static String dataAutoCheck(String str) throws UnsupportedEncodingException {
Pattern p = null; // 正则表达式
Matcher m = null; // 操作的字符串
String[] sp = validate.split("\\|");
for (int i = 0; i < sp.length; i++) {
p = Pattern.compile(sp[i].trim().toLowerCase());
m = p.matcher(str.toLowerCase());
if (m.find())
return sp[i].trim();
}
return "RSRIGHT";
}
}
三,添加XSSHttpServletRequestWraper.java
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang.StringUtils;
/**
* <p>
* Title: XSSHttpServletRequestWraper
* </p>
* <p>
* Description: XSS防御请求处理类
* </p>
*
* @author msCall
* @date 2018-9-12
*/
public class XSSHttpServletRequestWraper extends HttpServletRequestWrapper{
public XSSHttpServletRequestWraper(HttpServletRequest request) {
super(request);
}
/**
*覆盖基类的getParameter()方法,对请求参数的值进行过滤。
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
//Constants.MY_LOG.debug("getParameter----->转义处理");
//return clearXss(super.getParameter(name));// 保留勿删
if (null == value) return null;
return xssEncode(value.trim());
}
/**
*覆盖基类的getHeader()方法,对请求参数的值进行过滤。
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
//Constants.MY_LOG.debug("getHeader----->转义处理");
//return clearXss(super.getHeader(name)); // 保留勿删
if (null == value) return null;
return xssEncode(value);
}
/**
*覆盖基类的getParameterValues()方法,对请求参数的值进行过滤。
*/
@Override
public String[] getParameterValues(String name) {
//Constants.MY_LOG.debug("getParameterValues----->转义处理");
if(!StringUtils.isEmpty(name)){
String[] values = super.getParameterValues(name);
if(values != null && values.length > 0){
String[] newValues = new String[values.length];
for(int i =0; i< values.length; i++){
//newValues[i] = clearXss(values[i]);// 保留勿删
newValues[i] = xssEncode(values[i]);
}
return newValues;
}
}
return null;
}
@SuppressWarnings("unchecked")
public Map<String,String[]> getParameterMap() {
Map<String,String[]> map = new HashMap<String,String[]>();
Map<String,String[]> paramMap = (Map<String,String[]>) super.getParameterMap();
for (Iterator iterator = paramMap.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<String,String[]> entry = (Map.Entry<String,String[]>) iterator.next();
String [] values = entry.getValue();
for (int i = 0; i < values.length; i++) {
if(values[i] instanceof String){
values[i] = xssEncode(values[i]);
}
}
//entry.setValue(values);//不支持tomcat7
map.put(entry.getKey(), values);
}
return map;
}
/**
*
* 处理字符转义【勿删,请保留该注释代码】
* @param value
* @return
private String clearXss(String value){
if (value == null || "".equals(value)) {
return value;
}
value = value.replaceAll("<", "<").replaceAll(">", ">");
value = value.replaceAll("\\(", "(").replace("\\)", ")");
value = value.replaceAll("'", "'");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
value = value.replace("script", "");
return value;
}*/
/**
* 将特殊字符替换为全角
* @param s
* @return
*/
private String xssEncode(String s) {
if (s == null || s.isEmpty()) {
return s;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
//将特殊字符替换为全角
case '>':
sb.append('>');// 全角大于号 |\>|\<|\‘|\“|\\|\/|\(|\)
break;
case '<':
sb.append('<');// 全角小于号
break;
case '\'':
sb.append('‘');// 全角单引号
break;
//case '\"':
// sb.append('“');// 全角双引号
// break;
//case '&':
// sb.append('&');// 全角&
// break;
case '\\':
sb.append('\');// 全角斜线
break;
case '/':
sb.append('/');// 全角斜线
break;
//case '#':
// sb.append('#');// 全角井号
// break;
case '(':
sb.append('(');// 全角(号
break;
case ')':
sb.append(')');// 全角)号
break;
default:
sb.append(c);
break;
}
}
return sb.toString();
}
}
四,err_str_limite.jsp 跳转页面展示
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page contentType="text/html;charset=utf-8"%><html>
<style type="text/css">
#tip2 {
position: absolute;
right: 450px;
bottom: 0px;
height: 100px;
width: 260px;
border: 1px solid #CCCCCC;
background-color: #eeeeee;
padding: 1px;
overflow: hidden;
display: none;
font-size: 12px;
z-index: 10;
}
#tip2 p {
padding: 6px;
}
#tip2 h1,#detail h1 {
font-size: 14px;
height: 25px;
line-height: 25px;
background-color: #0066CC;
color: #FFFFFF;
padding: 0px 3px 0px 3px;
filter: Alpha(Opacity = 100);
}
#tip2 h1 a,#detail h1 a {
float: right;
text-decoration: none;
color: #FFFFFF;
}
</style>
<script type="text/javascript">
window.onload = function() {
var divTip = document.createElement("div");
divTip.id = "tip2";
divTip.style.top = '0px';
divTip.style.margin = '0,auto,0,0';
divTip.style.height = '0px';
divTip.style.bottom = '0px';
divTip.style.position = 'fixed';
document.body.appendChild(divTip);
start();
setInterval("start()", 300000);
}
var handle;
function start() {
var obj = document.getElementById("tip2");
obj.innerHTML = "<h1><a href='javascript:void(0)' onclick='start()'>×</a>提示</h1><p>输入包含非法数据,</br>例如,--,',\",\\,;,%,>,!,<,</br>iframe,frame,SYS.TAB,script,</br>alert,src,href等</p>";
if (parseInt(obj.style.height) == 0) {
obj.style.display = "block";
handle = setInterval("changeH('up')", 20);
}else {
handle = setInterval("changeH('down')", 20)
}
}
function changeH(str) {
var obj = document.all ? document.all["tip2"] : document.getElementById("tip2");
if (str == "up") {
if (parseInt(obj.style.height) > 150) {
clearInterval(handle);
} else {
obj.style.height=(parseInt(obj.style.height) + 8).toString() + "px";
}
}
if (str == "down") {
if (parseInt(obj.style.height) < 8) {
clearInterval(handle);
obj.style.display = "none";
} else {
obj.style.height = (parseInt(obj.style.height) - 8).toString() + "px";
}
}
}
</script>
五,验证成功。