跨站腳本攻擊—XSS

  • 2019 年 10 月 4 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/FE_dev/article/details/100876661

XSS 介紹

XSS 是跨站腳本攻擊(Cross Site Scripting)的簡寫,但是從首寫字母命名的方式來看,應該取名 CSS,但這樣就和層疊樣式表(Cascading Style Sheets,CSS)重名了,所以取名為 XSS。

XSS 攻擊,一般是指攻擊者通過在網頁中注入惡意腳本,當用戶瀏覽網頁時,惡意腳本執行,控制用戶瀏覽器行為的一種攻擊方式。

XSS 危害

  • 竊取用戶Cookie,獲取用戶隱私,盜取用戶帳號。
  • 劫持用戶(瀏覽器)會話,從而執行任意操作,例如進行非法轉賬、強制發表日誌、發送電子郵件等。
  • 強制彈出廣告頁面,刷流量等。
  • 傳播跨站腳本蠕蟲,網頁掛馬等。
  • 結合其他漏洞,如 CSRF 漏洞,實施進一步的攻擊。

XSS 分類

XSS 攻擊按是否把攻擊數據存進伺服器端,攻擊行為是否伴隨著攻擊數據一直存在,可分為 非持久型 XSS 攻擊持久型 XSS 攻擊

XSS 攻擊按攻擊方式又可分為 反射型 XSSDOM 型 XSS存儲型 XSS,其中 反射型 XSS 和 DOM 型 XSS 算是 非持久型 XSS 攻擊,而 存儲型 XSS 算是 持久型 XSS 攻擊。

反射型 XSS(Reflected XSS)

攻擊者誘導用戶訪問一個帶有惡意程式碼的 URL 後,伺服器端接收數據後處理,然後把帶有惡意程式碼的數據發送到瀏覽器端,瀏覽器端解析這段帶有 XSS 程式碼的數據後當做腳本執行,最終完成 XSS 攻擊。

因為這個過程就像一次反射,故稱為反射型 XSS。

攻擊步驟:

1、攻擊構造出特殊的 URL ,其中包含惡意程式碼。

2、用戶被誘導打開帶有惡意程式碼的 URL,伺服器端將惡意程式碼從 URL 中取出當做參數處理,然後返回給用戶帶有惡意程式碼的數據。

3、用戶瀏覽器接收到響應解析執行,混在其中的惡意程式碼也被執行。

4、惡意程式碼竊取用戶敏感數據發送給攻擊者,或者冒充用戶的行為,調用目標網站介面執行攻擊者指定的操作。

舉例

下面是一個正常的搜索流程

1、打開首頁,輸入搜索內容

https://www.kkkk1000.com/xss/Reflected/index.html

2、開始搜索,查看結果

https://www.kkkk1000.com/xss/Reflected/searchResult.html?kw=斗羅大陸

但是如果沒有搜索到結果,後端也會返回用戶輸入的內容,然後顯示在頁面上。

https://www.kkkk1000.com/xss/Reflected/searchResult.html?kw=xxx

因為這裡沒有對用戶輸入的數據做處理,所以我們構造這樣一個鏈接:

https://www.kkkk1000.com/xss/Reflected/searchResult.html?kw=<script>alert("xss")</script>

然後誘導他人點擊這個鏈接,就可以完成一次反射型 XSS 攻擊。

而對於這麼長的鏈接,我們還可以偽裝偽裝,轉為短網址或者二維碼。

短網址:

http://i6q.cn/4TJcII

二維碼:

也許你覺得只是一個彈框而已,問題不大,但如果我們把攻擊程式碼變為載入一個第三方的 js 文件呢?變為用 document.cookie 盜取 cookie 的程式碼呢?總之如果是真的攻擊的話,就不會只是一個彈框這麼簡單了。

DOM 型 XSS(DOM-based XSS)

DOM 型 XSS 形成原因是通過修改頁面的 DOM 節點形成的 XSS。

DOM 型 XSS 攻擊中,取出和執行惡意程式碼都由瀏覽器端完成,屬於前端自身的安全漏洞。

攻擊步驟:

1、攻擊者構造出特殊的 URL,其中包含惡意程式碼。

2、用戶被誘導打開帶有惡意程式碼的 URL。

3、用戶瀏覽器接收到響應後解析執行,前端 JavaScript 取出 URL 中的惡意程式碼並執行。

4、惡意程式碼竊取用戶數據並發送到攻擊者的網站,或者冒充用戶的行為,調用目標網站介面執行攻擊者指定的操作。

舉例

下面是一個物流詳情的頁面,在 URL 上有快遞編號這個參數,通過這個參數來獲取數據。

https://www.kkkk1000.com/xss/dom/index.html?serialNumber=YT40359134268305

因為在源碼中可以看到,頁面上顯示的快遞編號,是直接取的 URL 上的參數顯示的。所以我們構造這樣一個網址:

https://www.kkkk1000.com/xss/dom/index.html?serialNumber=<script>alert("xss")</script>

然後誘導他人點擊這個鏈接,就可以完成一次 DOM 型 XSS 攻擊。

存儲型 XSS(Stored XSS)

存儲型 XSS 跟 反射型 XSS 的區別是:存儲型 XSS 的惡意程式碼存在伺服器上,反射型 XSS 的惡意程式碼存在 URL 里。

存儲型 XSS 攻擊時惡意腳本會存儲在目標伺服器上。當瀏覽器請求數據時,腳本從伺服器傳回並執行。它是最危險的一種跨站腳本,比反射性 XSS 和 DOM 型 XSS 都更有隱蔽性,因為它不需要用戶手動觸發。任何允許用戶存儲數據的 Web 程式都可能存在存儲型 XSS 漏洞。若某個頁面遭受存儲型 XSS 攻擊,所有訪問該頁面的用戶都會被 XSS 攻擊。

攻擊步驟:

1、攻擊者把惡意程式碼提交到目標網站的伺服器中。

2、用戶打開目標網站,網站伺服器端把帶有惡意程式碼的數據取出,當做正常數據返回給用戶。

3、用戶瀏覽器接收到響應解析執行,混在其中的惡意程式碼也被執行。

4、惡意程式碼竊取用戶敏感數據發送給攻擊者,或者冒充用戶的行為,調用目標網站介面執行攻擊者指定的操作。

舉例

這是一個可以評論的文章的頁面

https://www.kkkk1000.com/xss/Stored/index.html

但是,評論的內容是沒有處理過的,所以我們如果輸入這樣的內容:

<script>alert("xss")</script>

同樣是可以作為評論的。

我們用這樣的內容作為評論後,所有打開這篇文章的用戶都會遭到存儲型 XSS 攻擊。

防禦方法

瀏覽器自帶防禦 (X-XSS-Protection

HTTP X-XSS-Protection 響應頭是 Internet Explorer,Chrome 和 Safari 的一個功能,當檢測到跨站腳本攻擊(XSS)時,瀏覽器將停止載入頁面。

他可以設置4個值:

X-XSS-Protection: 0  禁止XSS過濾。    X-XSS-Protection: 1  啟用XSS過濾(通常瀏覽器是默認的)。 如果檢測到跨站腳本攻擊,瀏覽器將清除頁面(刪除不安全的部分)。    X-XSS-Protection: 1; mode=block  啟用XSS過濾。 如果檢測到攻擊,瀏覽器將不會清除頁面,而是阻止頁面載入。    X-XSS-Protection: 1; report=<reporting-uri>  啟用XSS過濾。 如果檢測到跨站腳本攻擊,瀏覽器將清除頁面並使用CSP report-uri指令的功能發送違規報告。

這種瀏覽器自帶的防禦功能只對反射型 XSS 有一定的防禦力,其原理是檢查 URL 和 DOM 中元素的相關性,但這並不能完全防止反射型 XSS,而且也並不是所有瀏覽器都支援 X-XSS-Protection

轉義

在 XSS 攻擊中,攻擊者主要是通過構造特殊字元來注入腳本,所以對用戶的輸入進行檢測就很有必要,並且需要在客戶端與服務端都進行輸入檢測,然後對用戶輸入的數據進行轉義。

主要就是對輸入所包含的特殊字元進行轉義,如 <>&"',來防止 XSS 攻擊。

下面是一個用於轉義的方法:

function escapeHTML(str) {      if (!str) return '';      str = str.replace(/&/g, "&amp;");      str = str..replace(/</g, "&lt;");      str = str..replace(/>/g, "&gt;");      str = str..replace(/"/g, """);      str = str..replace(/'/g, "&#39;");      return str;  };

過濾

在富文本中因為需要保留 HTML ,所以我們不能使用轉義的方法防禦 XSS 攻擊,這裡使用過濾的方式防禦 XSS 攻擊,也就是通過只使用白名單允許的 HTML 標記及其屬性,來防禦攻擊。

這裡推薦一個名為 XSS 的組件 ,這就是一個根據白名單過濾 HTML,防止 XSS 攻擊的組件。

內容安全策略(CSP)

內容安全策略(Content Security Policy,CSP),實質就是白名單制度,開發者明確告訴客戶端,哪些外部資源可以載入和執行,大大增強了網頁的安全性。

兩種方法可以啟用 CSP。一種是通過 HTTP 頭資訊的 Content-Security-Policy 的欄位。

Content-Security-Policy: script-src 'self';    object-src 'none';    style-src cdn.example.org third-party.org;    child-src https:

另一種是通過網頁的 <meta> 標籤。

<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 做了如下配置。

  • 腳本: 只信任當前域名
  • <object>標籤: 不信任任何 URL,即不載入任何資源
  • 樣式表: 只信任 cdn.example.org 和 third-party.org
  • 頁面子內容,如 <frame><iframe> 必須使用HTTPS協議載入
  • 其他資源: 沒有限制

啟用後,不符合 CSP 的外部資源就會被阻止載入。

總結

XSS 攻擊的本質就是輸入的內容被當做程式執行了,所以我們對於用戶輸入的內容不能完全的信任,需要考慮如何避免其被當做程式執行。