xss攻击
request包装类
public class InjectionAttackWrapper extends HttpServletRequestWrapper {
private static final String EVENTS = "((?i) onload|onunload|onchange|onsubmit|onreset"
+ "|onselect|onblur|onfocus|onkeydown|onkeypress|onkeyup|onerror|script|alert"
+ "|onclick|ondblclick|onmousedown|onmousemove|onmouseout|onfScripTocus|alscRiPtert|onmouseover|onmouseup)";
private static final String XSS_HTML_TAG = "(%3C)|(%3E)|[<>]+";
private static final String XSS_INJECTION = "((%22%20)|(%22\\s)|('%22)|(%22\\+))\\w.*|(\\s|%20)"
+ EVENTS + ".*|(%3D)|(%7C)";
private static final String XSS_REGEX = XSS_HTML_TAG + "|" + XSS_INJECTION;
private static final String SQL_REGEX = "('.+--)|(--)|(\\|)|(%7C)";
private static final String HTTPEVENTS = "((?i)href|location|window|src|<|>|%3C|%3E)";
boolean filterXSS = true;
boolean filterSQL = true;
boolean filterWhite=true;
boolean filterHttpXss=false;
public boolean isFilterHttpXss() {
return filterHttpXss;
}
public void setFilterHttpXss(boolean filterHttpXss) {
this.filterHttpXss = filterHttpXss;
}
private byte[] body;
public InjectionAttackWrapper(HttpServletRequest request,
boolean filterXSS, boolean filterSQL,boolean filterWhite,boolean filterHttpXss) {
super(request);
this.filterXSS = filterXSS;
this.filterSQL = filterSQL;
this.filterHttpXss = filterHttpXss;
String contentType = request.getContentType();
if(StringUtils.isNotBlank(contentType) && StringUtils.indexOf(contentType, "application/json") >= 0) {
try {
body = IOUtils.toByteArray(super.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public InjectionAttackWrapper(HttpServletRequest request) {
this(request, true, true,false,false);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return filterParamString(value);
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> rawMap = super.getParameterMap();
Map<String, String[]> filteredMap = new HashMap<String, String[]>(
rawMap.size());
Set<String> keys = rawMap.keySet();
for (String key : keys) {
String[] rawValue = rawMap.get(key);
String[] filteredValue = filterStringArray(rawValue);
filteredMap.put(key, filteredValue);
}
return filteredMap;
}
protected String[] filterStringArray(String[] rawValue) {
String[] filteredArray = new String[rawValue.length];
for (int i = 0; i < rawValue.length; i++) {
filteredArray[i] = filterParamString(rawValue[i]);
}
return filteredArray;
}
@Override
public String[] getParameterValues(String name) {
String[] rawValues = super.getParameterValues(name);
if (rawValues == null)
return null;
String[] filteredValues = new String[rawValues.length];
for (int i = 0; i < rawValues.length; i++) {
filteredValues[i] = filterParamString(rawValues[i]);
}
return filteredValues;
}
@Override
public BufferedReader getReader() throws IOException {
if(body == null) {
return super.getReader();
}
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
if(body == null) {
return super.getInputStream();
}
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
};
}
public void filterJsonContext(){
try {
String jsonContent = IOUtils.toString(this.getInputStream());
jsonContent = this.filterParamString(jsonContent);
body = jsonContent.getBytes();
} catch (IOException e) {
e.printStackTrace();
}
}
protected String filterParamString(String rawValue) {
if (rawValue == null) {
return null;
}
if (filterXSS()) {
rawValue = rawValue.replaceAll(XSS_REGEX, "-");
}
if (filterSQL()) {
rawValue = rawValue.replaceAll(SQL_REGEX, "-");
}
if(isFilterWhite()){
rawValue = rawValue.replaceAll(EVENTS, "*");
}
if(isFilterHttpXss()){
rawValue = rawValue.replaceAll(HTTPEVENTS, "*");
}
return rawValue;
}
@Override
public String getQueryString() {
return filterParamString(super.getQueryString());
}
protected boolean filterXSS() {
return filterXSS;
}
protected boolean filterSQL() {
return filterSQL;
}
public boolean isFilterWhite() {
return filterWhite;
}
public void setFilterXSS(boolean filterXSS) {
this.filterXSS = filterXSS;
}
public void setFilterSQL(boolean filterSQL) {
this.filterSQL = filterSQL;
}
public void setFilterWhite(boolean filterWhite) {
this.filterWhite = filterWhite;
}
}
filter过滤器
public class InjectionAttackFilter implements Filter {
private static final String X_FRAME_VALUE = "SAMEORIGIN";
private static final String X_FRAME_HEADER = "X-FRAME-OPTIONS";
public static final String FILTER_XSS_PARAM_NAME = "filter_xss";
public static final String FILTER_SQL_INJECTION_PARAM_NAME = "filter_sql_injection";
public static final String CLICK_JACKING_HEADER = "click_jacking_header";
public static final String WHITE_LIST = "white_list";
public static final String HTTP_XSS = "filter_HttpXss";
boolean filterXSS = true;
boolean filterSQL = true;
boolean clickJacking = false;
boolean filterHttpXss = false;
private String whiteList = "";
private Logger log = Logger.getLogger(InjectionAttackFilter.class);
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
if (isFilter(servletRequest)) {
InjectionAttackWrapper wrapper = new InjectionAttackWrapper(
(HttpServletRequest) servletRequest, false, false,true,filterHttpXss);
filterChain.doFilter(wrapper, servletResponse);
} else {
String contentType = servletRequest.getContentType();
if (StringUtils.isNotBlank(contentType)) {
InjectionAttackWrapper wrapper = new InjectionAttackWrapper(
(HttpServletRequest) servletRequest, filterXSS, filterSQL,false,filterHttpXss);
if (StringUtils.indexOf(contentType, "application/json") >= 0) {
wrapper.setFilterXSS(false);
wrapper.setFilterSQL(true);
wrapper.setFilterWhite(true);
wrapper.filterJsonContext();
filterClickJack(servletResponse);
filterChain.doFilter(wrapper, servletResponse);
} else if (StringUtils.indexOf(contentType, "application/x-www-form-urlencoded") >= 0) {
filterChain.doFilter(wrapper, servletResponse);
}
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
private boolean isFilter(ServletRequest servletRequest) {
String[] wlist = this.getWhiteList();
boolean flag = false;
if (wlist != null && wlist.length > 0) {
HttpServletRequest reruest = (HttpServletRequest) servletRequest;
for (int i = 0; i < wlist.length; i++) {
if (StringUtils.indexOf(reruest.getRequestURI(),
StringUtils.replace(wlist[i], "*", "")) >= 0) {
flag = true;
break;
}
}
}
return flag;
}
private void filterClickJack(ServletResponse servletResponse) {
if (clickJacking) {
if (servletResponse instanceof HttpServletResponse) {
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
if (!httpServletResponse.containsHeader(X_FRAME_HEADER)) {
httpServletResponse
.addHeader(X_FRAME_HEADER, X_FRAME_VALUE);
}
}
}
}
private String[] getWhiteList() {
return StringUtils.split(whiteList, ",");
}
@Override
public void init(FilterConfig config) throws ServletException {
String filterXSSParam = config.getInitParameter(FILTER_XSS_PARAM_NAME);
String filterSQLParam = config
.getInitParameter(FILTER_SQL_INJECTION_PARAM_NAME);
String clickJackingParam = config
.getInitParameter(CLICK_JACKING_HEADER);
String clickHttpXss = config
.getInitParameter(HTTP_XSS);
whiteList = config.getInitParameter(WHITE_LIST);
filterXSS = new Boolean(filterXSSParam);
filterSQL = new Boolean(filterSQLParam);
clickJacking = new Boolean(clickJackingParam);
filterHttpXss = new Boolean(StringUtils.trimToEmpty(clickHttpXss));
}
}