- 接收前台post请求封装的
"versionDescription":"eeeeee",
时,莫名传到后台就变成"versionDeion":"eeeeee",
了。
- 找了半天,一直以后是前台的问题,一直在翻阅各种js代码。 后来,请教大佬,大佬一听到刚好少了
script
后,灵光乍现,感觉是拦截器的原因,后来查阅,果不其然。
- XSS 全称(Cross Site Scripting) 跨站脚本攻击, 是Web程序中最常见的漏洞。指攻击者在网页中嵌入客户端脚本(例如JavaScript), 当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的. 比如获取用户的Cookie,导航到恶意网站,携带木马等
- 参考https://www.cnblogs.com/xuxiu...
- 参考 http://www.cnblogs.com/jiangs...
- 参考 https://blog.csdn.net/qq_3292...
- 参考 https://blog.csdn.net/u012114...
- 这是一个预防XSS注入的拦截器,
web.xml
配置如下:
<filter>
<filter-name>xssFilter</filter-name>
<filter-class>com.cashew.utils.XssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>xssFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
package com.sgcc.utils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
public class XssFilter implements Filter {
Logger log = Logger.getLogger(this.getClass());
private static Pattern SCRIPT_PATTERN = Pattern
.compile("<script.*>.*<\\/script\\s*>");
private static Pattern HTML_PATTERN = Pattern.compile("<[^>]+>");
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
// 获得在下面代码中要用的request,response,session对象
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 设置cookie heetOnly
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
Cookie cookie = cookies[0];
if (cookie != null) {
// Servlet 2.5不支持在Cookie上直接设置HttpOnly属性
String value = cookie.getValue();
StringBuilder builder = new StringBuilder();
builder.append("JSESSIONID=" + value + "; ");
builder.append("Secure; ");
builder.append("HttpOnly; ");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, 30);
Date date = cal.getTime();
Locale locale = Locale.CHINA;
SimpleDateFormat sdf = new SimpleDateFormat(
"dd-MM-yyyy HH:mm:ss", locale);
builder.append("Expires=" + sdf.format(date));
response.setHeader("Set-Cookie", builder.toString());
}
}
String method = request.getMethod();
if("POST".equalsIgnoreCase(method)){
if (getParameterMap(request)) {
log.info("-----检测到危险字符,终止请求");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(JSONObject.fromObject(getFailedMap("检测到疑似注入操作,终止请求")).toString());
return;
}
}else{
boolean isScri = this.filterHtmlStr(request);
boolean isSql = this.filterSql(request);
if (!isScri || !isSql) {
log.info("检测到危险字符,终止请求");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(JSONObject.fromObject(getFailedMap("检测到疑似注入操作,终止请求")).toString());
return;
}
}
//chain.doFilter(servletRequest, servletResponse);
chain.doFilter(new XSSRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
/**
* 方法说明 :通过获取map的方法
*/
@SuppressWarnings("rawtypes")
private boolean getParameterMap(HttpServletRequest request) {
Map map = request.getParameterMap();
boolean illegalStr = false;
if (map != null) {
Set set = map.entrySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Entry) iterator.next();
if (entry.getValue() instanceof String[]) {
//System.out.println("==A==entry的key�? " + entry.getKey());
String[] values = (String[]) entry.getValue();
for (int i = 0; i < values.length; i++) {
if(!entry.getKey().toString().equals("buildJsonSettings")){
if(!filterSqlFromSream(values[i]) || !filterHtmlStr(values[i])){
System.out.println("1====非法字符 key=" +entry.getKey().toString() + ";value=" + values[i]);
illegalStr = true;
break;
}
}
}
} else if (entry.getValue() instanceof String) {
if(!filterSqlFromSream(entry.getValue().toString()) || !filterHtmlStr(entry.getValue().toString())){
System.out.println("2====非法字符 key=" +entry.getKey().toString() + ";value=" + entry.getValue().toString());
illegalStr = true;
break;
}
}
}
}
return illegalStr;
}
public boolean filterHtmlStr(String inputStr) {
Matcher mHtml = HTML_PATTERN.matcher(inputStr);
if (mHtml.find()) {
log.info("1------------------------Html str:" + inputStr);
return false;
}
Matcher m = SCRIPT_PATTERN.matcher(inputStr);
if (m.find()) {
log.info("1------------------------js str:" + inputStr);
return false;
}
return true;
}
public boolean filterHtmlStr(HttpServletRequest request) {
Map<String, String[]> paramMap = request.getParameterMap();
String lowStr = null;
Set<Entry<String, String[]>> keSet = paramMap.entrySet();
for (Iterator<Entry<String, String[]>> itr = keSet.iterator(); itr
.hasNext();) {
@SuppressWarnings("rawtypes")
Map.Entry me = (Map.Entry) itr.next();
Object ov = me.getValue();
String[] value = new String[1];
if (ov instanceof String[]) {
value = (String[]) ov;
} else {
value[0] = ov.toString();
}
for (int k = 0; k < value.length; k++) {
lowStr = value[k];
Matcher mHtml = HTML_PATTERN.matcher(lowStr);
if (mHtml.find()) {
log.info("2------------------------Html str:" + lowStr);
return false;
}
Matcher m = SCRIPT_PATTERN.matcher(lowStr);
if (m.find()) {
log.info("2------------------------js str:" + lowStr);
return false;
}
}
}
return true;
}
public boolean filterSql(HttpServletRequest request) {
Enumeration<String> params = request.getParameterNames();
String sql = "";
String name = "";
while (params.hasMoreElements()) {
name = params.nextElement().toString();
log.info(String.format("name is [%s]", name));
String[] value = request.getParameterValues(name);
for (int i = 0; i < value.length; i++) {
sql += value[i] + " ";
}
}
sql = sql.toLowerCase();
String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|chr|mid|truncate|"
+ "char|declare|sitename|net user|xp_cmdshell|or|like'|and|exec|execute|insert|create|drop|"
+ "table|from|grant|use|group_concat|column_name|"
+ "information_schema.columns|table_schema|union|where|order|by|count|*|"
+ "chr|mid|truncate|char|declare|or|like";
String[] badStrs = badStr.split("\\|");
String[] param = sql.split(" ");
for (int j = 0; j < param.length; j++)
for (int i = 0; i < badStrs.length; i++) {
if (param[j].equalsIgnoreCase(badStrs[i])) {
log.info(String.format("1------------查询到SQL注入,输入参数:[%s]", sql));
return false;
}
}
return true;
}
public boolean filterSqlFromSream(String inputJson) {
String sql = "";
try {
sql = URLDecoder.decode(inputJson,"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|chr|mid|truncate|"
+ "char|declare|sitename|net user|xp_cmdshell|or|like'|and|exec|execute|insert|create|drop|"
+ "table|from|grant|use|group_concat|column_name|"
+ "information_schema.columns|table_schema|union|where|order|by|count|*|"
+ "chr|mid|truncate|char|declare|or|like";
String[] badStrs = badStr.split("\\|");
String[] param = sql.split(" ");
for (int j = 0; j < param.length; j++)
for (int i = 0; i < badStrs.length; i++) {
if (param[j].equalsIgnoreCase(badStrs[i])) {
log.info(String.format("2------------查询到SQL注入,输入参数:[%s]", sql));
return false;
}
}
return true;
}
public String checkSpecialWord(String str) {
return Pattern
.compile(
"[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#�?%…�??&*()—�??+|{}【�?��?�;:�?��?��?��?�,、?]")
.matcher(str).replaceAll("").trim();
}
private Map<String, String> getFailedMap(String message) {
Map<String, String> ret = new HashMap<String,String>();
ret.put("status", "failed");
ret.put("message", message);
return ret;
}
class XSSRequestWrapper extends HttpServletRequestWrapper {
public XSSRequestWrapper(HttpServletRequest request) {
super(request);
}
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
value = cleanXSS(value);
}
return value;
}
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null) {
for (int i = 0; i < values.length; i++) {
values[i] = cleanXSS(values[i]);
}
}
return values;
}
private String cleanXSS(String value) {
value = value.replaceAll("<", "<").replaceAll(">", ">");
if(value.toLowerCase().contains("<script") || value.toLowerCase().contains("</script>") ){
value = value.substring(0,value.toLowerCase().indexOf("script"))+value.substring(value.toLowerCase().indexOf("script")+6);
}
return value;
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。