防止XSS攻击
2018-10-30 本文已影响0人
Lymen_lcm
关于什么是XSS攻击这里就不说明了,百度一下有很多解释,这里只是做一个自己的修补记录,仅供参考。
这里主要参考了公司的一位大神写的工具类,再做点修改
代码
首页在web.xml里面去添加一个全局拦截器
<!-- xss过滤器 -->
<filter>
<filter-name>XssSqlFilter</filter-name>
<filter-class>com.XXX.common.filter.XSSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>XssSqlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后是filter
package com.XXX.common.filter;
import com.XXX.common.utils.XssUtil;
import com.XXX.common.wrapper.XssHttpServletRequestWrapper;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 防止xss攻击 过滤器(顺便过滤了 sql攻击)
* @SINCE 2018/10/30 10:27
* @AUTHOR LCM
* @Param
* @return
*/
public class XSSFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ServletRequest requestWrapper = null;
request.setCharacterEncoding("UTF-8");
if(request instanceof HttpServletRequest) {
requestWrapper = new XssHttpServletRequestWrapper((HttpServletRequest) request);
}
if(requestWrapper == null) {
chain.doFilter(request, response);
} else {
try {
if(XssUtil.existsSQLInject(((XssHttpServletRequestWrapper) requestWrapper).getBody().toString())) {
throw new Exception("请求包含非法字符");
}else {
chain.doFilter(requestWrapper, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
// chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
@Override
public void destroy() {
}
}
filter引用了工具类XssUtil,XssHttpServletRequestWrapper
package com.XXX.common.utils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* XSS 防御工具类
* @since 2015-4-23
* @author BENSON
* @version 1.1
*/
public class XssUtil {
// Log4j日志对象
private static final Logger logger = Logger.getLogger(XssUtil.class);
// 特殊字符
public static final String REGEX_SPECIAL_CHARS = "[()+{}]";
//public static final String REGEX_SPECIAL_CHARS = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
// 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
public static final String REGEX_SCRIPT = "[\\<\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
// 定义script的正则表达式<script
public static final String REGEX_SCRIPT_START = "<script";
// 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
public static final String REGEX_STYLE = "[\\<\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
// 定义HTML标签的正则表达式
public static final String REGEX_HTML = "<[^>]+>";
// 定义window.location脚本的正则表达式
public static final String REGEX_LOCATION = "[\\s]*?window.location[\\s]*?|[\\s]*?window\\['location'\\][\\s]*?";
// 定义HTML的事件标签,如onclick等方法
public static String REGEX_HTML_ACTION = "";
//初始化定义HTML的事件标签
static {
REGEX_HTML_ACTION += "(";
String regexHtmlActionArray[] = {
"onblur","onchange","oncontextmenu","onfocus","onformchange",
"onforminput","oninput","oninvalid","onreset","onselect",
"onsubmit","onkeydown","onkeypress","onkeyup","onclick",
"ondblclick","ondrag","ondragend","ondragenter",
"ondragleave","ondragover","ondragstart","ondrop","onmousedown",
"onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel",
"onscroll","onmouseenter","onunload","onload","onabort",
"onerror","onresize"
};
for(String regexHtmlAction : regexHtmlActionArray){
REGEX_HTML_ACTION += "(" + regexHtmlAction + ")|";
}
REGEX_HTML_ACTION = REGEX_HTML_ACTION.substring(0, REGEX_HTML_ACTION.length() - 1);
REGEX_HTML_ACTION += ")";
}
// 定义alert脚本的正则表达式
//public static final String REGEX_ALERT = "[\\<\\s]*?alert[\\(\\s]*?[\\)]*?";
/**
* 过滤掉HTML可能存在的XSS的标签
* @param inputString 输入的字符串
* @return 过滤后的文本
*/
public static String html2Text(String inputString) {
String htmlStr = inputString; // 含html标签的字符串
String textStr = "";
Pattern p_script;
Matcher m_script;
Pattern p_style;
Matcher m_style;
/*
* java.util.regex.Pattern p_html; java.util.regex.Matcher m_html;
*/
try {
String regEx_Java = "[J|j][\\s]*[\\n]*[A|a][\\s]*[\\n]*[V|v][\\s]*[\\n]*[A|a][\\s]*[\\n]*";
String regEx_cookie = "[D|d][\\s]*[\\n]*[O|o][\\s]*[\\n]*[C|c][\\s]*[\\n]*[U|u][\\s]*[\\n]*[M|m][\\s]*[\\n]*[E|e][\\s]*[\\n]*[N|n][\\s]*[\\n]*[T|t][\\s]*[\\n]*\\.[C|c][\\s]*[\\n]*[O|o]{2}[\\s]*[\\n]*[K|k][\\s]*[\\n]*[I|i][\\s]*[\\n]*[E|e][\\s]*[\\n]*";
String regEx_location = "[W|w][\\s]*[\\n]*[I|i][\\s]*[\\n]*[N|n][\\s]*[\\n]*[D|d][\\s]*[\\n]*[O|o][\\s]*[\\n]*[W|w][\\s]*[\\n]*\\.[L|l][\\s]*[\\n]*[O|o][\\s]*[\\n]*[C|c][\\s]*[\\n]*[A|a][\\s]*[\\n]*[T|t][\\s]*[\\n]*[I|i][\\s]*[\\n]*[O|o][\\s]*[\\n]*[N|n][\\s]*[\\n]*\\s*";
// String regEx_alert = "[A|a][\\s]*[\\n]*[L|l][\\s]*[\\n]*[E|e][\\s]*[\\n]*[R|r][\\s]*[\\n]*[T|t][\\s]*[\\n]*\\s*\\(.*\\)";
String regEx_alert = "[A|a][\\s]*[\\n]*[L|l][\\s]*[\\n]*[E|e][\\s]*[\\n]*[R|r][\\s]*[\\n]*[T|t]";
// String regEx_alert = "alert";
String regEx_lt_script = "<[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t]>";
String regEx_gt_script = "</[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t]>";
String regEx_script = "<[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
// String regEx_script = "<script[^>]*?>[\\\\s\\\\S]*?<\\\\/script>";
String regEx_codescript = "<[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>[\\s\\S]*?<[\\s]*?%2f[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
// String regEx_codescript = "<script[^>]*?>[\\\\s\\\\S]*?<\\\\/script>";
String regEx_onlyscript = "<[\\s]*?[S|s][\\s]*[\\n]*[C|c][\\s]*[\\n]*[R|r][\\s]*[\\n]*[I|i][\\s]*[\\n]*[P|p][\\s]*[\\n]*[T|t][\\s]*[\\n]*[^>]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
// String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
p_script = Pattern.compile(regEx_Java, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤 java标签
System.out.println("过滤 java:"+htmlStr);
p_script = Pattern.compile(regEx_cookie, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤 document.cookie标签
System.out.println("过滤 cookie:"+htmlStr);
p_script = Pattern.compile(regEx_location, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤window.location标签
System.out.println("过滤 location:"+htmlStr);
p_script = Pattern.compile(regEx_alert, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤alert标签
System.out.println("过滤 alert:"+htmlStr);
p_script = Pattern.compile(regEx_lt_script, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤alert标签
System.out.println("过滤 ltscript:"+htmlStr);
p_script = Pattern.compile(regEx_gt_script, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤alert标签
System.out.println("过滤 gtscript:"+htmlStr);
p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤script标签
System.out.println("过滤 script:"+htmlStr);
p_script = Pattern.compile(regEx_codescript,
Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤codescript标签
System.out.println("过滤 regEx_codescript:"+htmlStr);
p_script = Pattern.compile(regEx_onlyscript,
Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤onlyscript标签
System.out.println("过滤 onlyscript:"+htmlStr);
p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
m_style = p_style.matcher(htmlStr);
htmlStr = m_style.replaceAll(""); // 过滤style标签
System.out.println("过滤 style:"+htmlStr);
/*
* p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
* m_html = p_html.matcher(htmlStr); htmlStr =
* m_html.replaceAll(""); // 过滤html标签
*/
// System.out.println("html:"+htmlStr);
textStr = htmlStr;
} catch (Exception e) {
logger.error("html2Text: " + e.getMessage());
}
return textStr;// 返回文本字符串
}
/**
* 将容易引起XSS漏洞的半角字符直接替换成全角字符
*
* @param s 需要转换的文本
* @return
*/
public static String xssEncode(String s) {
if (StringUtil.isNullString(s)) {
return s;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '>':
// sb.append(">");//全角大于号
sb.append(">");// 全角大于号
break;
case '<':
// sb.append("<");//全角小于号
sb.append("<");// 全角大于号
break;
case '\'':
sb.append('‘');// 全角单引号
break;
case '\"':
// sb.append(""");//全角双引号
sb.append(""");// 全角双引号
break;
case '&':
// sb.append("&");//全角
sb.append("&");// 全角
break;
case '\\':
sb.append('\');// 全角斜线
break;
case '#':
sb.append('#');// 全角井号
break;
default:
sb.append(c);
break;
}
}
return sb.toString();
}
/**
* 剔除XSS代码
* @param value 需要剔除的文本
* @return 剔除后文本
*/
public static String stripXSS(String value) {
// empty handle
if (StringUtil.isNullString(value)) {
return value;
}
// NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
// avoid encoded attacks.
// value = ESAPI.encoder().canonicalize(value);
// Remove all HTML tag
value = HtmlStringUtil.Html2Text(value);
System.out.println("Remove all HTML tag:" + value);
Pattern scriptPattern = null;
// Avoid anything in a src='...' type of expression
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid eval(...) expressions
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid expression(...) expressions
scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid javascript:... expressions
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid vbscript:... expressions
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid onload= expressions
scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid alert(...) expressions
scriptPattern = Pattern.compile("alert(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
System.out.println("Avoid alert(...) expressions:" + value);
// Avoid document.cookie
scriptPattern = Pattern.compile("document.cookie", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
System.out.println("Avoid document.cookie:" + value);
// Avoid event expressions
scriptPattern = Pattern.compile("event.*?", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
System.out.println("Avoid event expressions:" + value);
// Avoid function(...) expressions
scriptPattern = Pattern.compile("function(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
System.out.println("Avoid function(...) expressions:" + value);
// Avoid toString: expressions
scriptPattern = Pattern.compile("toString:", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
System.out.println("Avoid toString: expressions:" + value);
// Avoid location.href expressions
scriptPattern = Pattern.compile("location*?[.href][.host]", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
System.out.println("Avoid location.href expressions:" + value);
// Avoid Special characters
scriptPattern = Pattern.compile(REGEX_SPECIAL_CHARS);
value = scriptPattern.matcher(value).replaceAll("");
System.out.println("Avoid Special characters:" + value);
return value;
}
/**
* 剔除XSS代码
* @param value 需要剔除的文本
* @return 剔除后文本
*/
public static String escapeXSS(String value) {
// empty handle
if (StringUtil.isNullString(value)) {
return value;
}
System.out.println("\n---------------------------------------------------------------");
value = StringEscapeUtils.escapeHtml(value);
System.out.println("escapeHtml:" + value);
value = StringEscapeUtils.escapeJavaScript(value);
System.out.println("escapeJavaScript:" + value);
value = StringEscapeUtils.escapeCsv(value);
System.out.println("escapeCsv:" + value);
value = StringEscapeUtils.escapeXml(value);
System.out.println("escapeXml:" + value);
value = StringEscapeUtils.escapeSql(value);
System.out.println("escapeSql:" + value);
value = StringEscapeUtils.escapeJava(value);
System.out.println("escapeJava:" + value);
System.out.println("---------------------------------------------------------------\n");
return value;
}
/**
* 校验是否包含跨站脚本攻击或者SQL注入代码
* @param input 输入的数据
* @return 结果:TURE-包含 OR FALSE-不包含
*/
public static boolean checkXSS(String input) {
// empty handle
if (StringUtil.isNullString(input)) {
return false;
}
//br标签吞了
input = input.replaceAll("<br/>", "");
// script脚本匹配
Matcher scriptMatcher = Pattern.compile(REGEX_SCRIPT, Pattern.CASE_INSENSITIVE).matcher(input);
if (scriptMatcher.find()) {
System.out.println("REGEX_SCRIPT XSS");
return true;
}
// scriptStart脚本匹配
scriptMatcher = Pattern.compile(REGEX_SCRIPT_START, Pattern.CASE_INSENSITIVE).matcher(input);
if (scriptMatcher.find()) {
System.out.println("REGEX_SCRIPT_START XSS");
return true;
}
// style标签匹配
scriptMatcher = Pattern.compile(REGEX_STYLE, Pattern.CASE_INSENSITIVE).matcher(input);
if (scriptMatcher.find()) {
System.out.println("REGEX_STYLE XSS");
return true;
}
// HTML标签匹配
scriptMatcher = Pattern.compile(REGEX_HTML, Pattern.CASE_INSENSITIVE).matcher(input);
if (scriptMatcher.find()) {
System.out.println("REGEX_HTML XSS");
return true;
}
// 特殊字符匹配
// scriptMatcher = Pattern.compile(REGEX_SPECIAL_CHARS, Pattern.CASE_INSENSITIVE).matcher(input);
// if (scriptMatcher.find()) {
// System.out.println("REGEX_SPECIAL_CHARS XSS" + scriptMatcher.group(0));
// System.out.println(input);
// return true;
// }
// window.location匹配
scriptMatcher = Pattern.compile(REGEX_LOCATION, Pattern.CASE_INSENSITIVE).matcher(input);
if (scriptMatcher.find()) {
System.out.println("REGEX_LOCATION XSS");
return true;
}
// html事件标签匹配
scriptMatcher = Pattern.compile(REGEX_HTML_ACTION, Pattern.CASE_INSENSITIVE).matcher(input);
if (scriptMatcher.find()) {
System.out.println("REGEX_HTML_ACTION XSS");
return true;
}
boolean isExists = XssUtil.existsSQLInject(input);
if(isExists) {
return true;
}
return false;
}
/**
* 判断是否存在SQL注入
* @param src 当前访问路径
* @return
*/
public static boolean existsSQLInject(String src) {
if (StringUtil.isNullString(src)) {
return false;
}
List<String> list = SqlKeysCache.getSqlKeysList();
String str = src.toLowerCase();
for (int i = 0; i < list.size(); i++) {
if (str.contains(list.get(i))) {
System.out.println("输入信息存在SQL注入攻击!" + list.get(i));
logger.error("输入信息存在SQL注入攻击!" + list.get(i));
return true;
}
}
return false;
}
/*public static void main(String[] args) {
String input = null;
String tips = null;
input = "SCRIPT>var a = document.cookie; alert(a);</SCRIPT>";
tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
System.out.println("1" + tips);
input = "style> .input{font-color:red};</style>";
tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
System.out.println("2" + tips);
input = "<DIV> <a href='www.baidu.com'>baidu</a></div>";
tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
System.out.println("3" + tips);
input = "http://www.lzsmw.net/visit/interactionPage/toPubMailDetail?msgCode=\"&x='abc',new Function(x)()+\"";
tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
System.out.println("4" + tips);
input = "http://www.lzsmw.net/visit/approvePage/toOrderWindowFloor?programId=window['location']&asddf";
tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
System.out.println("5" + tips);
input = "http://www.lzsmw.net/visit/interactionPage/toPubMailDetail?msgCode=123¶m=ok";
tips = checkXSS(input)?"系统警告:包含有XSS攻击代码!":"代码正常。";
System.out.println("6" + tips);
}*/
public static void main(String[] args) {
String input = "{\"lmType\":{\"type\":\"1\"}}";
String ss ="{\"articleInfo\":{\"uuid\":\"\",\"articleId\":\"\",\"articleType\":\"1\"," +
"\"modifyDate\":\"2018-09-15 18:07\",\"sortId\":\"f39c315d323b4186913665b95fa7a4b7\"," +
"\"terminal\":\"\",\"title\":\"测试<script>alert(11234)</script>\",\"author\":\"教超管\"," +
"\"origin\":\"测试<script>alert(11234)</script>\",\"content\":\"<p>测试<script>alert(11234)<" +
"/script></p><p>测试<script>alert(134567)</script></p><p>测试<script>alert(145555)" +
"</script></p><p>测试<script>alert(157777)</script></p><p>测试<script>alert" +
"(13434324)</script></p><p><strong><131231231231231231231231231231231234123>" +
"</strong></p><p><strong><br/></strong></p><p><span style=\\\"text-decoration: underline;" +
"\\\"><strong><br/></strong></span></p><p><span style=\\\"text-decoration: underline;" +
"\\\"><strong><strong style=\\\"white-space: normal;\\\"><" +
"131231231231231231231231231231231234123></strong><strong style=\\\"white-space: normal;\\\"><" +
"131231231231231231231231231231231234123></strong><strong><" +
"131231231231231231231231231231231234123></strong><strong><" +
"</strong></strong></span><strong><strong>131231231231231231231231231231231234123>" +
"</strong><strong><1312312312312312312312312</strong><span style=\\\"color: rgb(147, 137, 83);" +
"\\\"><strong>31231231234123></strong><strong><131231231231231231231231231231231234123>" +
"</strong><strong><131231231231231231231231231231231234123></strong></span></strong></p><p " +
"style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: " +
"nowrap; top: 34px;\\\">测试<script>alert(11234)</script></p><p style=\\\"position: " +
"absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 34px;" +
"\\\"><br/></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: " +
"-1000px; white-space: nowrap; top: 39px;\\\">测试<script>alert(11234)</script></p><p " +
"style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: " +
"nowrap; top: 39px;\\\"><br/></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: " +
"hidden; left: -1000px; white-space: nowrap; top: 44px;\\\">测试<script>alert(11234)<" +
"/script></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: " +
"-1000px; white-space: nowrap; top: 44px;\\\">测试<script>alert(11234)</script></p><p " +
"style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: " +
"nowrap; top: 44px;\\\"><br/></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: " +
"hidden; left: -1000px; white-space: nowrap; top: 49px;\\\">测试<script>alert(11234)<" +
"/script></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: hidden; left: " +
"-1000px; white-space: nowrap; top: 49px;\\\"><br/></p><p style=\\\"position: absolute; width: 1px; " +
"height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 49px;\\\">测试<script>" +
"alert(11234)</script></p><p style=\\\"position: absolute; width: 1px; height: 1px; overflow: " +
"hidden; left: -1000px; white-space: nowrap; top: 49px;\\\"><br/></p><p style=\\\"position: absolute; " +
"width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 54px;\\\">测试<" +
"script>alert(11234)</script></p><p style=\\\"position: absolute; width: 1px; height: 1px; " +
"overflow: hidden; left: -1000px; white-space: nowrap; top: 54px;\\\"><br/></p><p style=\\\"position: " +
"absolute; width: 1px; height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 59px;" +
"\\\">测试<script>alert(11234)</script>v</p><p style=\\\"position: absolute; width: 1px; " +
"height: 1px; overflow: hidden; left: -1000px; white-space: nowrap; top: 59px;\\\"><br/></p>\"," +
"\"cover\":\"\",\"isPermit\":\"\",\"keyword\":\"\",\"stickStatus\":0,\"startDate\":\"\"," +
"\"endDate\":\"\",\"deptId\":\"\",\"roleId\":\"\",\"userId\":\"education\",\"promulgator\":\"教超管\"," +
"\"publishStatus\":0,\"auditStatus\":0,\"fsetId\":\"\",\"flowId\":\"\"},\"articleAuthList\":[]}";
System.out.println(XssUtil.html2Text(ss));
// 特殊字符匹配
Matcher scriptMatcher = Pattern.compile(REGEX_SPECIAL_CHARS, Pattern.CASE_INSENSITIVE).matcher(input);
if (scriptMatcher.find()) {
System.out.println("REGEX_SPECIAL_CHARS XSS");
System.out.println(scriptMatcher.group(0));
System.out.println(input);
}
}
}
package com.XXX.common.wrapper;
import com.XXX.common.utils.XssUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
/**
* HttpServletRequest包装器,用于防御XSS攻击
* @since 2015 4 23
* @author BENSON
* @version 1.1
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final String body;
protected static Logger logger = LoggerFactory.getLogger(XssHttpServletRequestWrapper.class);
public XssHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream,Charset.forName("UTF-8")));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = XssUtil.html2Text(stringBuilder.toString());
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
ServletInputStream servletInputStream = new ServletInputStream() {
public boolean isFinished() {
return false;
}
public boolean isReady() {
return false;
}
public void setReadListener(ReadListener readListener) {}
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream(),"UTF-8"));
}
public String getBody() {
return this.body;
}
/**
* 覆盖getHeader方法,将参数名和参数值都做XSS过滤。<br/>
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
* getHeaderNames 也可能需要覆盖
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
value = XssUtil.stripXSS(value);
return value;
}
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
// 空处理
if (null == values) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = XssUtil.stripXSS(values[i]);
}
return encodedValues;
}
/**
* 覆盖getParameter方法,将参数名和参数值都做XSS过滤。<br/>
*/
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
value = XssUtil.stripXSS(value);
return value;
}
}
package com.XXX.common.utils;
import java.util.regex.Pattern;
/**
* html标签工具类
* @author kermit
*
*/
public class HtmlStringUtil {
/**
* 过滤html的标签
* @param inputString
* @return
*/
public static String Html2Text(String inputString) {
String htmlStr = inputString; // 含html标签的字符串
String textStr = "";
Pattern p_script;
java.util.regex.Matcher m_script;
Pattern p_style;
java.util.regex.Matcher m_style;
Pattern p_html;
java.util.regex.Matcher m_html;
Pattern p_space;
java.util.regex.Matcher m_space;
try {
String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
// String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
// }
String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
// String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
// }
String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
String regEx_space = " ";
p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
m_script = p_script.matcher(htmlStr);
htmlStr = m_script.replaceAll(""); // 过滤script标签
p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
m_style = p_style.matcher(htmlStr);
htmlStr = m_style.replaceAll(""); // 过滤style标签
p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
m_html = p_html.matcher(htmlStr);
htmlStr = m_html.replaceAll(""); // 过滤html标签
p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE);
m_space = p_space.matcher(htmlStr);
htmlStr = m_space.replaceAll(" ");//过滤 标签
textStr = htmlStr;
} catch (Exception e) {
System.err.println("Html2Text: " + e.getMessage());
}
return textStr;// 返回文本字符串
}
}
package com.XXX.common.utils;
import java.util.ArrayList;
import java.util.List;
/**
* SQL关键字缓存类(用于XXS攻击的检测.)
* @since 2015 6 14
* @author BENSON
* @version 1.1
*/
public class SqlKeysCache {
private static List<String> sqlKeysList = new ArrayList<String>(7) {
{
add(" insert ");
add(" update ");
add(" delete ");
add(" and ");
add(" or ");
add(" order ");
add(" by ");
add(" case ");
add(" when ");
add(" then ");
add(" else ");
}
};
// public static void init() {
// sqlKeysList = new ArrayList<String>(7);
// sqlKeysList.add(" insert ");
// sqlKeysList.add(" update ");
// sqlKeysList.add(" delete ");
// sqlKeysList.add(" and ");
// sqlKeysList.add(" or ");
// sqlKeysList.add(" order ");
// sqlKeysList.add(" by ");
// }
/**
* 获取SQL关键字集合
* @return
*/
public static List<String> getSqlKeysList() {
return sqlKeysList;
}
}