原文鏈接:http://www.cnblogs.com/chenty/p/5136834.html
最近,有個項目突然接到總部的安全漏洞報告,查看后知道是XSS攻擊。
問題描述:
在頁面上有個隱藏域:
<input type = "hidden" id = "action" value = "${action}"/>
當前頁面提交到Controller時,未對action屬性做任何處理,直接又回傳到頁面上
如果此時action被用戶惡意修改為:***"<script>alert(1);</script>"***
此時當頁面刷新時將執行alert(1),雖然錯誤不嚴重,但是任何安全隱患都應受到重視。
解決思路:
該問題是由於對用戶輸入數據(隱藏域)未做任何處理,導致非法數據被執行,那么解決該問題的核心思路就是對用戶數據做嚴格處理,對任何頁面傳遞的數據都不應過分信任,處理方法如下:
1.在頁面上對action參數做轉義處理,${action?html}(前端技術采用freemarker),但是此種方法只能對單個屬性有效,如果此時項目處於維護期且有大量此種問題,修復的難度較大且不便於統一維護
2.在服務端對用戶數據做轉義處理,此時需要創建一個filter,對request進行二次封裝,核心代碼如下:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringEscapeUtils;
public class XssRequestWrapper extends HttpServletRequestWrapper {
public XssRequestWrapper(HttpServletRequest request) {
super(request);
}
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) {
return null;
}
return StringEscapeUtils.escapeHtml4(value);
}
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values == null) {
return null;
}
String[] newValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
newValues[i] = StringEscapeUtils.escapeHtml4(values[i]);
}
return newValues;
}
}
XssRequestWrapper是對request進行的二次封裝,最核心的作用是對request中的參數進行轉義處理(需要用到commons-lang3.jar)
定義filter,核心的代碼如下:
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
chain.doFilter(new XssRequestWrapper(req), response);
}
在web.xml中配置指定請求進行過濾,可以有效防止xss攻擊
以上方法沒有解決本質問題,最本質的問題就是在編寫代碼時嚴禁將頁面傳遞的參數不做任何處理再次返回到頁面!
