1. 程式人生 > >XSS跨站指令碼攻擊(三)-- 結合Spring MVC框架

XSS跨站指令碼攻擊(三)-- 結合Spring MVC框架

1.web.xml中

<filter>  
<filter-name>xssFilter</filter-name>  
<filter-class>com.xxx.web.filter.XSSFilter</filter-class>  
</filter>  
<filter-mapping>  
<filter-name>xssFilter</filter-name>  
<url-pattern>/*</url-pattern>  
</filter-mapping>  

2.XSSFilter.java
package com.xxx.web.filter;  
  
import java.io.IOException;  
  
import javax.servlet.Filter;  
import javax.servlet.FilterChain;  
import javax.servlet.FilterConfig;  
import javax.servlet.ServletException;  
import javax.servlet.ServletRequest;  
import javax.servlet.ServletResponse;  
import javax.servlet.http.HttpServletRequest;  
import org.apache.commons.lang.StringEscapeUtils;
  
 public class XssFilter implements Filter {  
  
   FilterConfig  filterConfig;
   public void init(FilterConfig config) throws ServletException {  
       this.filterConfig =  filterConfig;
   }  
  
   public void doFilter(ServletRequest request, ServletResponse response,  
      FilterChain chain) throws IOException, ServletException {  
      XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);  
      chain.doFilter(xssRequest, response);  
   }  
  
   public void destroy() {  
      this.filterConfig =  null;
   }  
}
3.XssHttpServletRequestWrapper.java

某些情況下,我們不能對使用者資料進行嚴格的過濾,那我們也需要對標籤進行轉換。

less-than character (<)

&lt;

greater-than character (>)

&gt;

ampersand character (&)

&amp;

double-quote character (")

&quot;

space character( )

&nbsp;

Any ASCII code character whose code is greater-than or equal to 0x80

&#<number>, where <number> is the ASCII character value.

      比如使用者輸入:<script>window.location.href=”http://www.baidu.com”;</script>,儲存後最終儲存的會是:&lt;script&gt;window.location.href=&quot;http://www.baidu.com&quot;&lt;/script&gt;在展現時瀏覽器會對這些字元轉換成文字內容顯示,而不是一段可執行的程式碼。
package com.xxx.web.filter;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletRequestWrapper;  
  
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {  
public XssHttpServletRequestWrapper(HttpServletRequest request) {  
super(request);
}  
@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] = StringEscapeUtils.escapeHtml(values[i]);
    encodedValues[i] = this.escapeHtml(values[i]);
}
return encodedValues;  
}

@Override  
public String getParameter(String parameter) {  
String value = super.getParameter(parameter);  
if (value == null) {  
    return null;  
}  
   //return StringEscapeUtils.escapeHtml(value);
    return this.escapeHtml(value);
}  
  
/** 
* 重寫StringEscapeUtils.escapeHtml()方法,避免過濾中文 
* 
* @param s 
* @return 
*/  
private String escapeHtml(String s) {  
 if (s == null || s.isEmpty()) {  
   return "";  
 }  
StringBuilder sb = new StringBuilder("");  
for (int i = 0; i < s.length(); i++) {  
char c = s.charAt(i);  
switch (c) {  
case '>':  
sb.append('>');  
break;  
case '<':  
sb.append('<'); 
break;   
case '"':  
sb.append('"');
break;  
case '&':  
sb.append('&'); 
break;  
case 10:  
case 13:  
break; 
default:  
sb.append(c);  
break;  
}  
}  
return sb.toString();  
}   
} 
4.針對上面重寫StringEscapeUtils.escapeHtml()方法,主要是,從前端傳入後臺的資料,如果是中文的話,使用StringEscapeUtils.escapeHtml(value)就會把中文也轉碼了,這樣不是我們希望看到的。,因此需要重寫方法。

5.如果我們前端傳的引數是一個json串,那麼到了後端需要對雙引號特殊處理,比如:

前端:

var arrChoosed = [{"id":parseInt('10'),"name":"詹三"},{.....}];

ajax傳入後端引數為data:{'params':JSON.stringify(arrChoosed),.....}

後端:

String parameter = request.getParameter("params").replaceAll("&quot;","\"");

ObjectMapper mapper = new ObjectMapper();

List<Map<String,Object>> paramList = mapper.readValue(parameter,List.class);

6.針對Spring MVC中的@RequestParam獲取的引數,走的是3中的getParameterValues()方法