XSS 介紹
XSS 是跨站腳本攻擊(Cross Site Scripting)的簡寫,但是從首寫字母命名的方式來看,應該取名 CSS,但這樣就和層疊樣式表(Cascading Style Sheets,CSS)重名了,所以取名爲 XSS。
XSS 攻擊,一般是指攻擊者通過在網頁中注入惡意腳本,當用戶瀏覽網頁時,惡意腳本執行,控制用戶瀏覽器行爲的一種攻擊方式。
XSS 危害
-
竊取用戶Cookie,獲取用戶隱私,盜取用戶賬號。
-
劫持用戶(瀏覽器)會話,從而執行任意操作,例如進行非法轉賬、強制發表日誌、發送電子郵件等。
-
強制彈出廣告頁面,刷流量等。
-
傳播跨站腳本蠕蟲,網頁掛馬等。
-
結合其他漏洞,如 CSRF 漏洞,實施進一步的攻擊。
-
…
XSS 分類
XSS 攻擊按是否把攻擊數據存進服務器端,攻擊行爲是否伴隨着攻擊數據一直存在,可分爲 非持久型 XSS 攻擊 和 持久型 XSS 攻擊。
XSS 攻擊按攻擊方式又可分爲 反射型 XSS、DOM 型 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 攻擊。
而對於這麼長的鏈接,我們還可以僞裝僞裝,轉爲短網址或者二維碼。
短網址:
二維碼:
也許你覺得只是一個彈框而已,問題不大,但如果我們把攻擊代碼變爲加載一個第三方的 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, "&");
str = str..replace(/</g, "<");
str = str..replace(/>/g, ">");
str = str..replace(/"/g, """);
str = str..replace(/'/g, "'");
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 攻擊的本質就是輸入的內容被當做程序執行了,所以我們對於用戶輸入的內容不能完全的信任,需要考慮如何避免其被當做程序執行。
攻擊案例
這裏舉幾個真實的 XSS 攻擊案例,大家瞭解下。
-
站酷 https://www.cnblogs.com/chyingp/archive/2013/06/06/zcool-xss.html
-
QQ空間 https://www.secpulse.com/archives/8446.html
-
百度網盤 https://zhuanlan.zhihu.com/p/24249045
-
新浪微博 https://www.secpulse.com/archives/47226.html