關於XSS漏洞修復


  XSS即惡意腳本攻擊漏洞,詳細的描述網上介紹的很詳細。我說一下自己在工作中對這種漏洞的修復方案,僅供參考。

  第一階段:使用ESAPI

  這是一個Apache開發的安全組件,主要用於解決SQL注入和惡意腳本注入。

  使用ESAPI防止XSS攻擊時,首先應當配置過濾器(注意在過濾器中chain.doFilter(..)方法中的Request對象進行包裝,在包裝類中對請求參數進行篩選操作);其次將過濾器注冊到web.xml文件中;最后配置Request的包裝類,在其中對請求信息進行過濾。

 1 import java.io.IOException;
 2 import javax.servlet.Filter;
 3 import javax.servlet.FilterChain;
 4 import javax.servlet.FilterConfig;
 5 import javax.servlet.ServletException;
 6 import javax.servlet.ServletRequest;
 7 import javax.servlet.ServletResponse;
 8 import javax.servlet.http.HttpServletRequest;
 9 
10 /*
11  *配置XSS過濾器 
12  */
13 public class XSSFilter implements Filter {
14     @Override
15     public void init(FilterConfig filterConfig) throws ServletException {
16     }
17     @Override
18     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
19         throws IOException, ServletException {
20         chain.doFilter(new XSSRequestWrapper((HttpServletRequest) request), response);
21     }
22     @Override
23     public void destroy() {
24     }
25 }
View Code
 1 <!-- XSS攻擊防范 -->
 2 <filter>
 3     <filter-name>XSSFilter</filter-name>
 4     <filter-class>過濾器全類名</filter-class>
 5     </filter>
 6 <filter-mapping>
 7     <filter-name>XSSFilter</filter-name>
 8         <url-pattern>/*</url-pattern>
 9         <dispatcher>REQUEST</dispatcher>
10         <dispatcher>FORWARD</dispatcher>
11 </filter-mapping>
View Code
 1 import java.net.URLDecoder;
 2 import java.util.regex.Pattern;
 3 import javax.servlet.http.HttpServletRequest;
 4 import javax.servlet.http.HttpServletRequestWrapper;
 5 import org.owasp.esapi.ESAPI;
 6 
 7 /*
 8  * 對傳入參數進行校驗
 9  */
10 public class XSSRequestWrapper extends HttpServletRequestWrapper {
11     public XSSRequestWrapper(HttpServletRequest servletRequest) {
12         super(servletRequest);
13     }
14     @Override
15     public String[] getParameterValues(String parameter) {
16         String[] values = super.getParameterValues(parameter);        
17         if (values == null) {
18             return null;
19         }
20         int count = values.length;
21         String[] encodedValues = new String[count];
22         for (int i = 0; i < count; i++) {
23             encodedValues[i] = stripXSS(values[i]);
24         }
25         return encodedValues;
26     }
27     @Override
28     public String getParameter(String parameter) {
29         String value = super.getParameter(parameter);
30         return stripXSS(value);
31     }
32     @Override
33     public String getHeader(String name) {
34         String value = super.getHeader(name);
35         return stripXSS(value);
36     }
37 
38         private String stripXSS(String value) {
39         if (value != null) {
40             //解析URL編碼,防止前台的編碼后的參數進入ESAPI過濾后無法正常解碼
41             value = URLDecoder.decode(value);
42              // 使用ESAPI的防護功能避免XSS攻擊
43             value = ESAPI.encoder().canonicalize(value);
44             // 去除空字符
45             value = value.replaceAll("", "");
46             // 過濾腳本標簽間(如:<script>..</script>)的內容
47             Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
48             value = scriptPattern.matcher(value).replaceAll("");
49             //過濾由項目路徑(src)直接訪問項目資源的行為
50             scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
51             value = scriptPattern.matcher(value).replaceAll("");
52             scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
53             value = scriptPattern.matcher(value).replaceAll("");
54             // 過濾單個</script>標簽
55             scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
56             value = scriptPattern.matcher(value).replaceAll("");
57             // 過濾單個<script ...> 標簽
58             scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
59             value = scriptPattern.matcher(value).replaceAll("");
60             // 過濾 eval(...) 表達式
61             scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
62             value = scriptPattern.matcher(value).replaceAll("");
63             // 過濾e­xpression(...) 表達式
64             scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
65             value = scriptPattern.matcher(value).replaceAll("");
66             // 過濾javascript:表達式攻擊
67             scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
68             value = scriptPattern.matcher(value).replaceAll("");
69             // 過濾vbscript:表達式攻擊
70             scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
71             value = scriptPattern.matcher(value).replaceAll("");
72             // 過濾onload=事件
73             scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
74             value = scriptPattern.matcher(value).replaceAll("");
75         }
76         return value;
77     }
78 }
View Code

  注意:開啟ESAPI的防護功能時(value = ESAPI.encoder().canonicalize(value);),需要提前對要篩選的值進行URL解碼(value = URLDecoder.decode(value);),否則會出現中文亂碼。

  第二階段(可選):使用CSF(Content Security Policy)安全策略

  CSF是一種白名單防御策略,所有不在名單內的資源都不被信任,有效的防止了通過外部的標簽、腳本、JS文件等資源的入侵形式,詳情請看http://www.ruanyifeng.com/blog/2016/09/csp.html,我也是在這位大佬的網站上學習的CSF.

  使用方式:

  1.通過<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">標簽將CSP嵌入到頁面中。但是這種做法會對所有頁面添加一個過濾項,加長了頁面的訪問時間,降低了用戶體驗;我加到項目中的時候還出現了某些樣式文件加載不全的現象,沒有必要不建議這么做。

  2.通過使用Nginx配置HTTP 頭信息的Content-Security-Policy的字段,但是一般的公司都不允許更改Nginx,一旦Nginx做了某種配置,整個項目都受影響,這種方式基本沒戲。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM