1. 程式人生 > >XSS跨站指令碼攻擊以及解決辦法

XSS跨站指令碼攻擊以及解決辦法

來源:https://www.cnblogs.com/insaneXs/p/7465014.html

XSS,全稱為Cross Site Script,跨站指令碼攻擊,是WEB程式中一種常見的漏洞。其主要的攻擊手段是在在利用網站上的可由使用者輸入資訊的地方,惡意注入含有攻擊性的指令碼,達到攻擊網站或者竊取使用者cookied等隱私資訊的目的

XSS漏洞主要分為兩種型別,一種是Stored XSS, 另一種是反射型 XSS。

第一種舉個簡單的例子就是BBS網站,黑客可以利用留言的功能,發表以下內容:

<script type="text/javascript"> alert("surprise") </script>

  對系統而言,它認為這和其他的留言一樣都只是字串。但是當有使用者訪問到這個頁面時,瀏覽器會把這段留言當成html內容來解析。因此就執行了其中的js指令碼。

而反射型 XSS則是利用點選連結或是提交一些內容來達到攻擊的目的。

比如我有以下一個頁面:

<form  name="formsearch" method="get">
        <div class="form">
           <input name="q" type="text" class="search-keyword" id="search-keyword"  />
          <button type="submit" class="search-submit blue-button">搜尋</button>
        </div>
        </form>

 

  當用戶在input框中輸入:    "<script type="text/javascript"> alert(“surperise”) " 時。他也向瀏覽器插入了自己的JS指令碼。

  當表單被提交時,輸入的字串被作為引數放在了URL中,傳到下一個頁面。

  當下一個頁面需要顯示這些內容,字串中包含的攻擊指令碼也就被瀏覽器解釋了出來。

  

  當然這段指令碼只能在自己的瀏覽器執行,可能沒有什麼攻擊性,但是黑客們會想盡辦法偽裝頁面達到攻擊的目的。

 

  總之,XSS攻擊就是想辦法讓你的瀏覽器去執行他的指令碼。

 

  那麼XSS攻擊該如何預防呢?

  既然是通過輸入字串達到植入指令碼的目的,那麼我們只要對使用者輸入的字串進行一個html轉義處理就好了。

  我們可以利用org.apache.commons.lang3.StringEscapeUtils(注:3.6版本起,用commons-text包下的StringEscapeUtils代替)這個類對輸入的引數進行html轉義。

  

  可以定義一個過濾器,然後轉義HttpServletRequest中的引數值。

  程式碼如下:

  定義攔截器

 1 import java.io.IOException;
 2 
 3 import javax.servlet.Filter;
 4 import javax.servlet.FilterChain;
 5 import javax.servlet.FilterConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.ServletRequest;
 8 import javax.servlet.ServletResponse;
 9 import javax.servlet.http.HttpServletRequest;
10 
11 public class XSSFilter implements Filter {
12     @Override  
13     public void init(FilterConfig filterConfig) throws ServletException {  
14         
15     }  
16       
17     @Override  
18     public void doFilter(ServletRequest request, ServletResponse response,  
19       FilterChain chain) throws IOException, ServletException {  
20             chain.doFilter(new XSSHttpServletRequestWrapper((HttpServletRequest) request), response);  
21     }  
22       
23     @Override  
24     public void destroy() {  
25         
26     }  
27 
28 
29 }

 由於原生的HttpServletRequest不支援你直接修改引數,因此我們定義了一個包裝類,在獲取引數的時候對引數進行轉義。

 1 package com.jspxcms.core.support;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 import javax.servlet.http.HttpServletRequestWrapper;
 5 
 6 import org.apache.commons.lang3.StringEscapeUtils;
 7 
 8 public class XSSHttpServletRequestWrapper extends HttpServletRequestWrapper {
 9 
10     public XSSHttpServletRequestWrapper(HttpServletRequest request) {
11         super(request);
12     }
13     
14     @Override  
15     public String getHeader(String name) {  
16         return StringEscapeUtils.escapeHtml4(super.getHeader(name));  
17     }  
18   
19     @Override  
20     public String getQueryString() {  
21         return StringEscapeUtils.escapeHtml4(super.getQueryString());  
22     }  
23   
24     @Override  
25     public String getParameter(String name) {  
26         return StringEscapeUtils.escapeHtml4(super.getParameter(name));  
27     }  
28   
29     @Override  
30     public String[] getParameterValues(String name) { 
31         String[] values = super.getParameterValues(name);  
32         if(values != null) {  
33             int length = values.length;  
34             String[] escapseValues = new String[length];  
35             for(int i = 0; i < length; i++){  
36                 escapseValues[i] = "1";  
37             }  
38             return escapseValues;  
39         }  
40         return super.getParameterValues(name);  
41     }  
42 }

    最後我們在web.xml中配置我們的攔截器即可(將XXXX換成類的全限定名)。 

1     <filter>  
2         <filter-name>XssEscape</filter-name>  
3         <filter-class>XXXXX.XSSFilter</filter-class>  
4     </filter>
5     <filter-mapping>  
6         <filter-name>XssEscape</filter-name>  
7         <url-pattern>/*</url-pattern>  
8         <dispatcher>REQUEST</dispatcher>  
9     </filter-mapping>  

  簡單的XSS防禦就完成了。