ink.huaxun.gateway.config.XssHttpServletRequestWrapper Maven / Gradle / Ivy
The newest version!
package ink.huaxun.gateway.config;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* @author zhubo
* @date 2020/5/29
*/
public class XssHttpServletRequestWrapper extends RequestWrapper {
private static final Logger logger = LoggerFactory.getLogger(XssHttpServletRequestWrapper.class);
private static final String[] KEY = {"and", "exec", "insert", "select", "delete", "update", "count", "*", "%", "chr", "mid", "master", "truncate", "char", "declare", ";", "or", "-", "+"};
private static final Set NOT_ALLOWED_KEY_WORDS = new HashSet<>(Arrays.asList(KEY));
private static final String REPLACED_STRING = "INVALID";
private final String currentUrl;
public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
super(servletRequest);
currentUrl = servletRequest.getRequestURI();
}
/**
* 覆盖getParameter方法,将参数名和参数值都做xss过滤。
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
*/
@Override
public String getParameter(String parameter) {
String value = super.getParameter(parameter);
if (value == null) {
return null;
}
return cleanXSS(value);
}
@Override
public String[] getParameterValues(String parameter) {
String[] values = super.getParameterValues(parameter);
if (values == null) {
return null;
}
int count = values.length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values[i]);
}
return encodedValues;
}
@Override
public Map getParameterMap() {
Map values = super.getParameterMap();
if (values == null) {
return null;
}
Map result = new HashMap<>();
for (String key : values.keySet()) {
String encodedKey = cleanXSS(key);
int count = values.get(key).length;
String[] encodedValues = new String[count];
for (int i = 0; i < count; i++) {
encodedValues[i] = cleanXSS(values.get(key)[i]);
}
result.put(encodedKey, encodedValues);
}
return result;
}
/**
* 覆盖getHeader方法,将参数名和参数值都做xss过滤。
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取
* getHeaderNames 也可能需要覆盖
*/
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
if (value == null) {
return null;
}
return cleanXSS(value);
}
public String cleanXSS(String value) {
value = cleanSqlKeyWords(value);
value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
value = value.replaceAll("'", "& #39;");
value = value.replaceAll("eval\\((.*)\\)", "");
value = value.replaceAll("[\"'][\\s]*javascript:(.*)[\"']", "\"\"");
value = value.replaceAll("script", "");
return value;
}
private String cleanSqlKeyWords(String value) {
String paramValue = value;
for (String keyword : NOT_ALLOWED_KEY_WORDS) {
if (paramValue.length() > keyword.length() + 4
&& (paramValue.contains(" " + keyword) || paramValue.contains(keyword + " ") || paramValue.contains(" " + keyword + " "))) {
paramValue = StringUtils.replace(paramValue, keyword, REPLACED_STRING);
logger.error(this.currentUrl + "已被过滤,因为参数中包含不允许sql的关键词(" + keyword
+ ")" + ";参数:" + value + ";过滤后的参数:" + paramValue);
}
}
return paramValue;
}
}