- 什么是XSS攻击
简单来说,XSS 攻击是页面被注入了恶意的代码,度娘一大堆的东西,不想说
- 系统架构主要是SSM框架,服务层另外使用了DubboX.
为啥说这个,因为SpringMVC对于Xss攻击需要特殊处理
- 思路
其实XSS工具解决思路就是捕获客户端提交的参数进行捕获,然后对参数值进行过滤处理,去除那些非法的字符.
但是请求通常分为GET请求与POST请求,针对不同的请求,处理方式是不一样的
- 步骤:
1.针对GET与非文件格式上传的post请求.(form 表单提交的时候 没有这个参数enctype="multipart/form-data"),JSON请求等
1) web.xml配置过滤器

1 <!-- xxs过滤 --> 2 <filter> 3 <filter-name>XssSqlFilter</filter-name> 4 <filter-class>cn.ffcs.web.filter.XssFilter</filter-class> 5 </filter> 6 <filter-mapping> 7 <filter-name>XssSqlFilter</filter-name> 8 <url-pattern>/*</url-pattern> 9 <dispatcher>REQUEST</dispatcher> 10 </filter-mapping>
2)过滤器实现 XssFilter.java,针对部分特殊请求,要求不走过滤的,可以在此过滤器中放行

1 package cn.ffcs.web.filter; 2 3 import java.io.IOException; 4 5 import javax.servlet.FilterChain; 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 import org.slf4j.Logger; 11 import org.slf4j.LoggerFactory; 12 import org.springframework.web.filter.OncePerRequestFilter; 13 14 public class XssFilter extends OncePerRequestFilter { 15 private final Logger logger = LoggerFactory.getLogger(this.getClass()); 16 @Override 17 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) 18 throws ServletException, IOException { 19 try { 20 String uri = request.getRequestURI(); 21 //特殊url不走过滤器 22 if (uri.contains("receipt") || uri.contains("mobile/buildingMgr") 23 || uri.contains("bestPay") || uri.contains("backNotify") || uri.contains("frontNotify") 24 || uri.contains("queryOrder") || uri.contains("refundNotify") || uri.contains("refund") 25 || uri.contains("reverse")) { 26 chain.doFilter(request, response); 27 } else { 28 XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); 29 chain.doFilter(xssRequest, response); 30 } 31 } catch (Exception e) { 32 logger.error("Xss过滤器,包装request对象失败"); 33 chain.doFilter(request, response); 34 } 35 } 36 }
3) XssHttpServletRequestWrapper

1 package cn.ffcs.web.filter; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletRequestWrapper; 5 6 public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { 7 8 HttpServletRequest orgRequest = null; 9 10 public XssHttpServletRequestWrapper(HttpServletRequest request) { 11 super(request); 12 orgRequest = request; 13 } 14 15 /** 16 * 覆盖getParameter方法,将参数名和参数值都做xss过滤 17 */ 18 @Override 19 public String getParameter(String name) { 20 String value = super.getParameter(xssEncode(name)); 21 if (value != null) { 22 value = xssEncode(value); 23 } 24 return value; 25 } 26 /** 27 * 覆盖getParameterValues方法,将参数名和参数值都做xss过滤 28 */ 29 public String[] getParameterValues(String parameter) { 30 String[] values = super.getParameterValues(parameter); 31 if (values==null) { 32 return null; 33 } 34 int count = values.length; 35 String[] encodedValues = new String[count]; 36 for (int i = 0; i < count; i++) { 37 encodedValues[i] = xssEncode(values[i]); 38 } 39 return encodedValues; 40 } 41 42 /** 43 * 获取request的属性时,做xss过滤 44 */ 45 @Override 46 public Object getAttribute(String name) { 47 Object value = super.getAttribute(name); 48 if (null != value && value instanceof String) { 49 value = xssEncode((String) value); 50 } 51 return value; 52 }; 53 54 /** 55 * 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/> 56 */ 57 @Override 58 public String getHeader(String name) { 59 String value = super.getHeader(xssEncode(name)); 60 if (value != null) { 61 value = xssEncode(value); 62 } 63 return value; 64 } 65 66 67 /** 68 * 将容易引起xss漏洞的半角字符直接替换成全角字符 69 * 70 * @param s 71 * @return 72 */ 73 private static String xssEncode(String s) { 74 return XssEncode.xssEncode(s); 75 } 76 77 /** 78 * 获取最原始的request 79 * 80 * @return 81 */ 82 public HttpServletRequest getOrgRequest() { 83 return orgRequest; 84 } 85 86 /** 87 * 获取最原始的request的静态方法 88 * 89 * @return 90 */ 91 public static HttpServletRequest getOrgRequest(HttpServletRequest req) { 92 if (req instanceof XssHttpServletRequestWrapper) { 93 return ((XssHttpServletRequestWrapper) req).getOrgRequest(); 94 } 95 96 return req; 97 } 98 99 100 }
4) 使用到的编码工具,过滤参数使用了xss-html-filter工具,具体可以自行替换

1 package cn.ffcs.web.filter; 2 3 import net.sf.xsshtmlfilter.HTMLFilter; 4 5 public class XssEncode { 6 public static String xssEncode(String s) { 7 if (s == null || s.isEmpty()) { 8 return s; 9 } 10 try { 11 HTMLFilter htmlFilter = new HTMLFilter(); 12 String clean = htmlFilter.filter(s); 13 return clean; 14 } catch (NullPointerException e) { 15 return s; 16 } catch (Exception ex) { 17 ex.printStackTrace(); 18 } 19 20 return null; 21 } 22 }
5) pom.xml 配置引用的jar

1 <dependency> 2 <groupId>net.sf.xss-html-filter</groupId> 3 <artifactId>xss-html-filter</artifactId> 4 <version>1.5</version> 5 </dependency>
2.针对enctype="multipart/form-data"格式的post提交
1) 更改springMVC默认Annotation适配器(org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter - -> cn.ffcs.web.filter.XssAnnotationMethodHandlerAdapter),如果没有则添加
1 <!-- annotation方法修饰器 --> 2 <bean id="handlerAdapter" class="cn.ffcs.web.filter.XssAnnotationMethodHandlerAdapter"> 3 4 .... 5 6 <bean>
2) 继承AnnotationMethodHandlerAdapter 并覆盖handle方法

1 package cn.ffcs.web.filter; 2 3 import java.util.Map; 4 import java.util.Set; 5 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import net.sf.xsshtmlfilter.HTMLFilter; 10 11 import org.apache.commons.lang.StringUtils; 12 import org.springframework.web.servlet.ModelAndView; 13 import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; 14 @SuppressWarnings("deprecation") 15 public class XssAnnotationMethodHandlerAdapter extends 16 AnnotationMethodHandlerAdapter { 17 18 19 @SuppressWarnings({ "rawtypes", "unchecked" }) 20 private void myXss(HttpServletRequest request){ 21 Map map = request.getParameterMap(); 22 Set<String> keySet = map.keySet(); 23 for(String key : keySet){ 24 String[] values = request.getParameterValues(key); 25 if(values!=null&&values.length>0){ 26 for(int i=0 ;i<values.length;i++){ 27 if(!StringUtils.isBlank(values[i])){ 28 values[i] = XssEncode.xssEncode(values[i]); 29 } 30 } 31 } 32 } 33 } 34 35 @Override 36 public ModelAndView handle(HttpServletRequest request, 37 HttpServletResponse response, Object handler) throws Exception { 38 myXss(request); 39 return super.handle(request, response, handler); 40 } 41 }
tip: 网上另外有说用反射实现带@Controller的控制器,感觉思路可以,但是没有成功.