解决XSS或CRSF等http注入攻击的问题
通过自定义请求头的方式,替换攻击头里面输入的特殊字符来解决
包装HttpServletRequest
自定义ProxyHttpServletRequest包装HttpServletRequest的请求,需要继HttpServletRequestWrapper类,重写getParameter和getParameterValues方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| package com.heagle.web.filter;
import org.apache.commons.lang.StringUtils;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper;
public class ProxyHttpServletRequest extends HttpServletRequestWrapper {
private static String script_start="<script>";
private static String script_end="</script>";
public ProxyHttpServletRequest(HttpServletRequest request) { super(request); }
@Override public String getParameter(String name) { String targetValue=this.getRequest().getParameter(name); if(StringUtils.isBlank(targetValue)){ return targetValue; } return scriptFilter(targetValue); }
@Override public String[] getParameterValues(String name) { String[]targetValues=this.getRequest().getParameterValues(name); if(targetValues==null||targetValues.length==0){ return targetValues; } String []resultValues=targetValues; for(int i=0;i<targetValues.length;i++){ String value=targetValues[i]; resultValues[i]= scriptFilter(value); } return resultValues; }
private String scriptFilter(String source) { return source.replace(script_start,"").replace(script_end,""); }
}
|
包装MultipartHttpServletRequest
自定义ProxyDefaultMultipartHttpServletRequest来包装MultipartHttpServletRequest的请求,需要继承spring默认实现的DefaultMultipartHttpServletRequest请求,同样也是重写getParameter和getParameterValues方法来解决.注意自定义请求类,引用父类构造方法时要引用三参构造方法,不然父类的私有属性会没有初始化.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| package com.heagle.web.filter;
import org.apache.commons.lang.StringUtils; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
public class ProxyDefaultMultipartHttpServletRequest extends DefaultMultipartHttpServletRequest{
private static String script_start="<script>";
private static String script_end="</script>";
public ProxyDefaultMultipartHttpServletRequest(MultipartHttpServletRequest request) { super(request,request.getFileMap(),request.getParameterMap()); }
public String getParameter(String name) { String targetValue = ""; String[] values = (String[])((String[])this.getMultipartParameters().get(name)); if (values != null) { targetValue = values.length > 0 ? values[0] : null; } else { targetValue = super.getParameter(name); } if(StringUtils.isNotBlank(targetValue)){ return scriptFilter(targetValue); }else{ return null; }
}
public String[] getParameterValues(String name) { String[] targetValues = (String[])((String[])this.getMultipartParameters().get(name)); if(targetValues == null){ targetValues = super.getParameterValues(name); } if(targetValues == null || targetValues.length ==0){ return targetValues; } String []resultValues=targetValues; for(int i=0;i<targetValues.length;i++){ String value=targetValues[i]; resultValues[i]= scriptFilter(value); } return resultValues; }
private String scriptFilter(String source) { return source.replace(script_start,"").replace(script_end,""); }
}
|
doFilter方法说明
在自定义过滤器里面判断请求类型,然后根据请求类型创建不同的自定义请求对象,注意如果是MultipartRequest,需要在过滤器类里面先根据multipartResolver#resolveMultipart方法初始化创建MultipartHttpServletRequest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Override public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain chain) throws IOException, ServletException { String contentType = request.getContentType(); HttpServletRequest xssRequest = null; if (contentType != null && contentType.toLowerCase().contains("multipart")) { xssRequest = new ProxyDefaultMultipartHttpServletRequest(getRequest(request)); }else { xssRequest = new ProxyHttpServletRequest(request); } chain.doFilter(xssRequest, response); }
private MultipartHttpServletRequest getRequest(ServletRequest req){ String enctype = req.getContentType(); if (StringUtils.isNotBlank(enctype) && enctype.contains("multipart")) return multipartResolver.resolveMultipart((HttpServletRequest) req); else return null; }
|