引言
我曾做過一個調查,看看網友們對關於X-XSS-Protection 字段的設置中,哪一個設置是最差的,調查結果令我非常吃驚,故有此文。
網友們認為 最差的配置是X-XSS-Protection: 0,其次是 X-XSS-Protection: 1; mode=block, 反而X-XSS-Protection: 1 成了不是最差的配置了。在我看來(其他人也可能和我持有同樣觀點),X-XSS-Protection: 1 應該是最差的配置。
在這篇文章中,我會和大家一起討論有關X-XSS-Protection的配置,最后希望大家明白什么樣的X-XSS-Protection配置才是有安全隱患的。
科普下相關知識
從IE8 開始,IE 瀏覽器內置了一個針對XSS攻擊的防護機制,這個瀏覽器內置的防護機制就是所謂的XSS filter,這個防護機制主要用於減輕反射型XSS 攻擊帶來的危害。 基於Webkit 內核的瀏覽器(比如Chrome)隨后也增加一個名為XSS auditor 的防護機制,作用和IE中的XSS filter類似。這兩種XSS防護機制的目的都很簡單,如果瀏覽器檢測到了含有惡意代碼的輸入被呈現在HTML文檔中,那么這段呈現的惡意代碼要么被刪除,要么被轉義,惡意代碼不會被正常的渲染出來,當然了,瀏覽器是否要攔截這段惡意代碼取決於瀏覽器的XSS防護設置。
至於怎么設置瀏覽器的XSS防護機制,其實很簡單,只要在HTTP響應報文的頭部增加一個X-XSS-Protection 字段,明確地告訴瀏覽器XSS filter/auditor該如何工作。 X-XSS-Protection 的字段有三個可選配置值
0: 表示關閉瀏覽器的XSS防護機制
1:刪除檢測到的惡意代碼, 如果響應報文中沒有看到X-XSS-Protection 字段,那么瀏覽器就認為X-XSS-Protection配置為1,這是瀏覽器的默認設置
1; mode=block:如果檢測到惡意代碼,則不再渲染文檔
0x02. X-XSS-Protection的默認配置並不安全
讓我們一起討論一下瀏覽器中關於X-XSS-Protection字段的默認設置。 其實默認設置有安全隱患的。
第一個安全隱患就是:
默認設置擴大了攻擊面, 比如攻擊者可以利用這個默認設置選擇性的刪除頁面中某些腳本,下圖就是一個例子
在上圖的例子中, jQuery 庫竟然被意外的刪除了,之所以會出現這樣的現象,是因為 瀏覽器的XSS auditor分不清jQuery庫是頁面本身自帶的還是攻擊者注入的。 如果這次被以外刪除的是一個和安全相關的js庫,你可以想象,攻擊者注入一個和含有js安全庫名字的惡意代碼,這樣就可以把這個js安全庫給刪除了。 類似這樣的攻擊手法已經出現了,點擊這里查看詳情
注:此隱患經測試,無論引入哪個js,最新版 Chrome 會拒絕加載所有 js,而不是單個 js。
第二個安全隱患是:
默認設置會引入新的漏洞,早在2009年,IE瀏覽器就因為XSS filter的缺陷被爆出一個UXSS漏洞。實際上,攻擊者可以將無害的標簽變成有害的標簽,因為過濾器有時候很傻,會不正確地替換了關鍵位置的字符,從而損害了原始文檔的結構。
通過精心制作的有效載荷,可以繞過屬性下文的限制。 最近,我發現很多類似UXSS的漏洞被發現,這些漏洞本質上的原因都是一樣的。
第三個安全隱患:
必然會有繞過XSS filter/auditor 的方法出現, 不信你可以看看以前被繞過的例子,比如這個, 這個, 這個, 還有這個。 從這些被繞過的案例中,我們可以發現,不管XSS filter/auditor 的過濾多么嚴格, 它總存在被繞過的可能, 此外,XSS filter/auditor 在某些場景下是有短板的,Chromium 小組曾經很明確的表明:XSS auditor 只是眾深防御的一環,完全靠它是無法防止所有的XSS攻擊。
好了。至此,大家對XSS filter/auditor 是可以被繞過的這一觀點沒有異議吧。 XSS filter/auditor的默認設置會部分刪除它認為的惡意代碼,這種做法有時候是有問題的,所以XSS-Protection: 1; mode=block這個設置是最好的了嘍?
咋一看,好像是沒了上述提到的問題,而且還能提供一定的防御能力,可不幸的是,這樣的配置還是會引入新的漏洞, 最明顯的一個例子就是 Refer 泄露的BUG,這個漏洞導致了Facebook賬戶劫持漏洞. 這也是Facebook 為什么選擇禁用XSS filter/auditor的原因。引入的漏洞不僅僅這一個,其他的漏洞比如這個, 還有這個。 當然了,和上述提到的漏洞相比,這種配置引入的漏洞還是相對少一點。
那么問題來了,最好的設置是什么
總而言之, 至於設置成XSS-Protection: 0還是XSS-Protection: 1; mode=block取決於你的業務場景,如果在你的業務場景中,你認為你的程序或系統是不會有XSS漏洞的, 或者是無法承擔XSS filter/auditor 特性引發的BUG,那你就選擇配置成前者;否則,你還是選擇配置成后者吧。 反正,老司機給你一句忠告就是,千萬別配置成XSS-Protection: 1
參考他人建議
並不是說 mode=block 或者 0 就是好,還要和具體業務、開發水平等相適配。如框架能有過濾轉義類、方法,開發人員安全水平高,白盒審計檢測完善,這個頭就可有可無。但對於一些快速發展期,框架不完善,業務為先等情況下,一個配置就能緩解一部分攻擊,還是可以考慮使用 1,而不是mode=block。對於問題一,經測試,無論引入哪個js,最新版 Chrome 會拒絕加載所有 js,而不是單個 js。
原文:https://blog.innerht.ml/the-misunderstood-x-xss-protection/