- 什么是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的控制器,感覺思路可以,但是沒有成功.
