245 lines
8.3 KiB
Plaintext
245 lines
8.3 KiB
Plaintext
package com.securityControl.common.security.utils;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.net.URLDecoder;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import javax.servlet.ReadListener;
|
|
import javax.servlet.ServletInputStream;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletRequestWrapper;
|
|
|
|
/**
|
|
* @author GeYazhong
|
|
* @date 2021/11/23 10:31
|
|
*/
|
|
@Slf4j
|
|
public class XssRequestWrapper extends HttpServletRequestWrapper {
|
|
private byte[] body;
|
|
|
|
private String queryString;
|
|
|
|
private String streamParam;
|
|
|
|
private boolean checked;
|
|
|
|
public XssRequestWrapper(HttpServletRequest request) {
|
|
super(request);
|
|
getParameterMap();
|
|
BufferedReader reader;
|
|
try {
|
|
reader = request.getReader();
|
|
StringBuilder sb = new StringBuilder();
|
|
char[] buf = new char[1024];
|
|
int rd;
|
|
while ((rd = reader.read(buf)) != -1) {
|
|
sb.append(buf, 0, rd);
|
|
}
|
|
reader.close();
|
|
|
|
streamParam = xssClean(sb.toString());
|
|
|
|
setChecked(xssCleanNew(sb.toString()) && xssCleanNew(request.getQueryString()));
|
|
body = streamParam.getBytes();
|
|
} catch (IOException e) {
|
|
log.error(e.getLocalizedMessage(),e);
|
|
}
|
|
|
|
queryString = xssClean(request.getQueryString());
|
|
|
|
}
|
|
|
|
@Override
|
|
public String getQueryString() {
|
|
return queryString;
|
|
}
|
|
|
|
@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 boolean isFinished() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isReady() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void setReadListener(ReadListener listener) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public int read() throws IOException {
|
|
int read = bais.read();
|
|
bais.close();
|
|
return read;
|
|
}
|
|
};
|
|
}
|
|
@Override
|
|
@SuppressWarnings("rawtypes")
|
|
public Map<String, String[]> getParameterMap() {
|
|
Map<String, String[]> request_map = super.getParameterMap();
|
|
if(request_map!=null){
|
|
Iterator iterator = request_map.entrySet().iterator();
|
|
// System.out.println("request_map" + request_map.size());
|
|
while (iterator.hasNext()) {
|
|
Map.Entry me = (Map.Entry) iterator.next();
|
|
// System.out.println("getParameterMap:=" + me.getKey() + ":");
|
|
String[] values = (String[]) me.getValue();
|
|
for (int i = 0; i < values.length; i++) {
|
|
if (values[i] != null) {
|
|
values[i] = xssClean(values[i]);
|
|
}
|
|
}
|
|
}}
|
|
return request_map;
|
|
}
|
|
|
|
@Override
|
|
public String[] getParameterValues(String paramString) {
|
|
String[] arrayOfString1 = super.getParameterValues(paramString);
|
|
if (arrayOfString1 == null){return null;}
|
|
int i = arrayOfString1.length;
|
|
String[] arrayOfString2 = new String[i];
|
|
|
|
for (int j = 0; j < i; j++) {
|
|
// System.out.println("getParameterValues:=" + arrayOfString1[j]);
|
|
if (arrayOfString1[j] != null) {
|
|
arrayOfString2[j] = xssClean(arrayOfString1[j]);
|
|
}
|
|
}
|
|
return arrayOfString2;
|
|
}
|
|
|
|
@Override
|
|
public String getParameter(String paramString) {
|
|
String str = super.getParameter(paramString);
|
|
if (str == null){return null;}
|
|
|
|
// System.out.println("getParameter:=" + str);
|
|
return xssClean(str);
|
|
}
|
|
|
|
@Override
|
|
public String getHeader(String paramString) {
|
|
String str = super.getHeader(paramString);
|
|
if (str == null){return null;}
|
|
// System.out.println("getHeader:=" + str);
|
|
return xssClean(str);
|
|
}
|
|
|
|
private String xssClean(String value) {
|
|
if (value == null) {
|
|
return value;
|
|
}
|
|
value = value.replaceAll("", "");
|
|
|
|
Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
|
|
value = scriptPattern.matcher(value).replaceAll("");
|
|
|
|
return value;
|
|
}
|
|
|
|
private boolean xssCleanNew(String value) {
|
|
boolean find = false;
|
|
if (value == null) {
|
|
return true;
|
|
}
|
|
List<Pattern> patterns = new ArrayList<Pattern>();
|
|
patterns.add(Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE));
|
|
patterns.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
|
|
patterns.add(Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
|
|
patterns.add(Pattern.compile("</script>", Pattern.CASE_INSENSITIVE));
|
|
patterns.add(Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
|
|
patterns.add(Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
|
|
patterns.add(Pattern.compile("e-xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
|
|
patterns.add(Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE));
|
|
patterns.add(Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE));
|
|
patterns.add(Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL));
|
|
|
|
for (Pattern pattern : patterns) {
|
|
find = match(pattern, value) ;
|
|
if (find) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
return !find;
|
|
}
|
|
|
|
/**
|
|
* 执行正则表达式
|
|
*
|
|
* @param pattern
|
|
* 表达式
|
|
* @param str
|
|
* 待验证字符串
|
|
* @return 返回 <b>true </b>,否则为 <b>false </b>
|
|
*/
|
|
private static boolean match(Pattern pattern, String str) {
|
|
Matcher m = pattern.matcher(str);
|
|
return m.find();
|
|
}
|
|
|
|
public String getReaderParam() {
|
|
return streamParam;
|
|
}
|
|
|
|
public boolean isChecked() {
|
|
return checked;
|
|
}
|
|
|
|
public void setChecked(boolean checked) {
|
|
this.checked = checked;
|
|
}
|
|
}
|