|
@@ -0,0 +1,656 @@
|
|
|
+package com.jiayue.ssi.servlet;
|
|
|
+
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.util.StreamUtils;
|
|
|
+
|
|
|
+import javax.servlet.ReadListener;
|
|
|
+import javax.servlet.ServletInputStream;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletRequestWrapper;
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.util.*;
|
|
|
+import java.util.regex.Pattern;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author code
|
|
|
+ * @version 1.0
|
|
|
+ * @Date 2023/2/7 10:38
|
|
|
+ * @Description ${DESCRIPTION}
|
|
|
+ */
|
|
|
+public class XssKeywordsHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
|
|
+
|
|
|
+ private final Logger logger = LoggerFactory.getLogger(XssKeywordsHttpServletRequestWrapper.class);
|
|
|
+
|
|
|
+ private String key = "and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+";
|
|
|
+ private Set<String> notAllowedKeyWords = new HashSet<String>(0);
|
|
|
+
|
|
|
+ HttpServletRequest orgRequest = null;
|
|
|
+ private Map<String, String[]> parameterMap;
|
|
|
+ private final byte[] body; //用于保存读取body中数据
|
|
|
+
|
|
|
+ public XssKeywordsHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
|
|
|
+ super(request);
|
|
|
+ orgRequest = request;
|
|
|
+ parameterMap = request.getParameterMap();
|
|
|
+ body = StreamUtils.copyToByteArray(request.getInputStream());
|
|
|
+
|
|
|
+ String keyStr[] = key.split("\\|");
|
|
|
+ for (String str : keyStr) {
|
|
|
+ notAllowedKeyWords.add(str);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重写几个HttpServletRequestWrapper中的方法
|
|
|
+ /**
|
|
|
+ * 获取所有参数名
|
|
|
+ *
|
|
|
+ * @return 返回所有参数名
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Enumeration<String> getParameterNames() {
|
|
|
+ Vector<String> vector = new Vector<String>(parameterMap.keySet());
|
|
|
+ return vector.elements();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 覆盖getParameter方法,将参数名和参数值都做xss & sql过滤。<br>
|
|
|
+ * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br>
|
|
|
+ * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String getParameter(String name) {
|
|
|
+ String[] results = parameterMap.get(name);
|
|
|
+ if (results == null || results.length == 0) {
|
|
|
+ return null;
|
|
|
+ }else {
|
|
|
+ String value = results[0];
|
|
|
+ if (value != null) {
|
|
|
+ value = xssEncode(value);
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, String[]> getParameterMap() {
|
|
|
+ Map<String,String[]> values = super.getParameterMap();
|
|
|
+ if(null == values){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Map<String,String[]> result = new HashMap<>();
|
|
|
+ for (String key : values.keySet()) {
|
|
|
+ String encodedKey = xssEncode(key);
|
|
|
+ int count = values.get(key).length;
|
|
|
+ String[] encodedValues = new String[count];
|
|
|
+ for(int i = 0;i < count;i++){
|
|
|
+ encodedValues[i] = xssEncode(values.get(key)[i]);
|
|
|
+ }
|
|
|
+ result.put(encodedKey,encodedValues);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定参数名的所有值的数组,如: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] = xssEncode(results[i]);
|
|
|
+ }
|
|
|
+ return results;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 覆盖getHeader方法,将参数名和参数值都做xss & sql过滤。<br>
|
|
|
+ * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br>
|
|
|
+ * getHeaderNames 也可能需要覆盖
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public String getHeader(String name) {
|
|
|
+
|
|
|
+ String value = super.getHeader(xssEncode(name));
|
|
|
+ if (value != null) {
|
|
|
+ value = xssEncode(value);
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将容易引起xss & sql漏洞的半角字符直接替换成全角字符
|
|
|
+ *
|
|
|
+ * @param s
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String xssEncode(String s) {
|
|
|
+ if (s == null || s.isEmpty()) {
|
|
|
+ return s;
|
|
|
+ } else {
|
|
|
+ s = stripXSSAndSql(s);
|
|
|
+ }
|
|
|
+ StringBuilder sb = new StringBuilder(s.length() + 16);
|
|
|
+ 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;
|
|
|
+ default:
|
|
|
+ sb.append(c);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取最原始的request
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public HttpServletRequest getOrgRequest() {
|
|
|
+ return orgRequest;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取最原始的request的静态方法
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unused")
|
|
|
+ public HttpServletRequest getOrgRequest(HttpServletRequest req) {
|
|
|
+ if (req instanceof XssKeywordsHttpServletRequestWrapper) {
|
|
|
+ return ((XssKeywordsHttpServletRequestWrapper) req).getOrgRequest();
|
|
|
+ }
|
|
|
+
|
|
|
+ return req;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * 防止xss跨脚本攻击(替换,根据实际情况调整)
|
|
|
+ */
|
|
|
+
|
|
|
+ public String stripXSSAndSql(String value) {
|
|
|
+ if (value != null) {
|
|
|
+ // NOTE: It's highly recommended to use the ESAPI library and
|
|
|
+ // uncomment the following line to
|
|
|
+ // avoid encoded attacks.
|
|
|
+ // value = ESAPI.encoder().canonicalize(value);
|
|
|
+ // Avoid null characters
|
|
|
+ /** value = value.replaceAll("", ""); ***/
|
|
|
+ // Avoid anything between script tags
|
|
|
+ Pattern scriptPattern = Pattern.compile(
|
|
|
+ "<[\r\n| | ]*script[\r\n| | ]*>(.*?)<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+ // Avoid anything in a
|
|
|
+ // src="http://www.yihaomen.com/article/java/..." type of
|
|
|
+ // e-xpression
|
|
|
+ scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+ // Remove any lonesome tag
|
|
|
+ scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+ // Remove any lonesome <script ...> tag
|
|
|
+ scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
|
|
|
+ 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 e-xpression(...) expressions
|
|
|
+ scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+ // Avoid javascript:... expressions
|
|
|
+ scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+ // Avoid vbscript:... expressions
|
|
|
+ scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+ // Avoid οnlοad= expressions
|
|
|
+ scriptPattern = Pattern.compile("onload(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("onerror(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("onmouse(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("scr*ipt(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("%3b(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ value = scriptPattern.matcher(value).replaceAll("");
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean checkXSSAndSql(String value) {
|
|
|
+ boolean flag = false;
|
|
|
+ if (value != null) {
|
|
|
+ Pattern scriptPattern = Pattern.compile(
|
|
|
+ "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile(
|
|
|
+ "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("scr*ipt(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("eval\\((.*?)\\)",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ // Avoid e-xpression(...) expressions
|
|
|
+ scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Avoid javascript:... expressions
|
|
|
+ scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ // Avoid vbscript:... expressions
|
|
|
+ scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ // Avoid οnlοad= expressions
|
|
|
+ scriptPattern = Pattern.compile("onload(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Avoid οnlοad= expressions
|
|
|
+ scriptPattern = Pattern.compile("onerror(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Avoid οnlοad= expressions
|
|
|
+ scriptPattern = Pattern.compile("onmouse(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<(.*?)img(.*?)src=(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("</STYLE>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("</scr(.*?)ipt>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("alert(.*?);|console(.*?);|confirm(.*?);|prompt(.*?);",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ flag = checkSqlKeyWords(value);
|
|
|
+ }
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean checkSqlKeyWords(String value){
|
|
|
+ String paramValue = value;
|
|
|
+ for (String keyword : notAllowedKeyWords) {
|
|
|
+ if (paramValue.length() > keyword.length() + 4
|
|
|
+ && (paramValue.contains(" "+keyword)||paramValue.contains(keyword+" ")||paramValue.contains(" "+keyword+" "))) {
|
|
|
+
|
|
|
+ logger.error(this.getRequestURI()+ "参数中包含不允许sql的关键词(" + keyword
|
|
|
+ + ")");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final boolean checkParameter() {
|
|
|
+
|
|
|
+ @SuppressWarnings({ "unchecked", "rawtypes" })
|
|
|
+ Map<String, String[]> submitParams = new HashMap(parameterMap);
|
|
|
+
|
|
|
+ Set<String> submitNames = submitParams.keySet();
|
|
|
+ for (String submitName : submitNames) {
|
|
|
+ Object submitValues = submitParams.get(submitName);
|
|
|
+ if ((submitValues instanceof String)) {
|
|
|
+ if (checkXSSAndSql((String) submitValues)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else if ((submitValues instanceof String[])) {
|
|
|
+ for (String submitValue : (String[])submitValues){
|
|
|
+ if (checkXSSAndSql(submitValue)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public BufferedReader getReader() throws IOException {
|
|
|
+ return new BufferedReader(new InputStreamReader(getInputStream()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ServletInputStream getInputStream() throws IOException {
|
|
|
+ final ByteArrayInputStream bais = new ByteArrayInputStream(body);
|
|
|
+ return new ServletInputStream() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int read() throws IOException {
|
|
|
+ return bais.read();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isFinished() {
|
|
|
+ // TODO Auto-generated method stub
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isReady() {
|
|
|
+ // TODO Auto-generated method stub
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setReadListener(ReadListener arg0) {
|
|
|
+ // TODO Auto-generated method stub
|
|
|
+
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean testxss(String value) {
|
|
|
+ boolean flag = false;
|
|
|
+ if (value != null) {
|
|
|
+ Pattern scriptPattern = Pattern.compile(
|
|
|
+ "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile(
|
|
|
+ "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("scr*ipt(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<!--[\r\n| | ]*script[\r\n| | ]*-->", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("eval\\((.*?)\\)",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ // Avoid e-xpression(...) expressions
|
|
|
+ scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Avoid javascript:... expressions
|
|
|
+ scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ // Avoid vbscript:... expressions
|
|
|
+ scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ // Avoid οnlοad= expressions
|
|
|
+ scriptPattern = Pattern.compile("onload(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Avoid οnlοad= expressions
|
|
|
+ scriptPattern = Pattern.compile("onerror(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Avoid οnlοad= expressions
|
|
|
+ scriptPattern = Pattern.compile("onmouse(.*?)=",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("<(.*?)img(.*?)src=(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("</STYLE>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ scriptPattern = Pattern.compile("</scr(.*?)ipt>", Pattern.CASE_INSENSITIVE);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptPattern = Pattern.compile("%3b(.*?)",
|
|
|
+ Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
|
+ flag = scriptPattern.matcher(value).find();
|
|
|
+ if (flag) {
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) throws Exception{
|
|
|
+ String str = "console.log(299792458)%3b";
|
|
|
+ if (str.indexOf("%3b")>0){
|
|
|
+ System.out.println("====");
|
|
|
+
|
|
|
+ }
|
|
|
+ System.out.println(XssKeywordsHttpServletRequestWrapper.testxss(str));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|