利用 onload 事件監控跨站資源

用過 CSP 的都很鬱悶,上報的只有違規的站點名,卻沒有具體路徑。這是缺陷,還是特意的設計?

顯然,CSP 是爲安全定製的,裏面的規範自然要嚴格制定,否則就會帶來新的安全問題。如果支持詳細路徑的上報,那又會引出什麼問題?

由於 CSP 會上報所有的請求,甚至包括重定向的,因此可以用來探測重定向後的地址。假如已登錄的用戶訪問 login.xx.com 會重定向到 xx.com/username,那麼攻擊者設計一個只允許重定向前的規則的頁面,用戶訪問後,重定向後的 URL 就會當做違規地址上報給攻擊者,這其中就包括了用戶名。

如果支持詳細路徑的上報,這簡直就是災難,就用來探測的用戶隱私信息了。事實上目前只上報主機名,都能進行一些利用,例如這篇 Using Content-Security-Policy for Evil

不過新的規範總是在改進,未來也許只上報重定向前的 URL。但在這之前,我們只能接受這些雞肋的上報日誌。

規則不靈活

CSP 目前只支持白名單列表,這多少有些死板。

更糟的是,不同規則之間無法繼承和共享。例如默認有個 default-src 規則,但其他的規則會覆蓋它,而不是繼承它。這就導致各個規則之間,出現很多的重複,使得整個字符串變的冗長。

無法和頁面交互

CSP 的監控和上報,是在瀏覽器後臺自動處理的,沒有提供一個事件供頁面進行交互。

這樣就只能使用統一方式強制處理了,而無法交給頁面腳本,更好的來自定義處理。

上報方式不可控

如果處理方式有多種選擇,那麼統一處理也無可厚非。

但事實上 CSP 的上報方式及格式,沒有任何可選餘地。只能使用 POST + JSON 的方式提交,並且其中的字段十分累贅,甚至把規則裏的白名單列表也發上來了。

此外,也無法設定一個緩存時間,控制重複上報的間隔。在配置白名單遺漏時,會出現大量的誤報,嚴重消耗資源。

浪費帶寬

在較新的 Chrome 裏,能夠使用 meta 標籤在前端頁面定義 CSP 規則,但其他瀏覽器目前仍不支持。

爲了能夠統一,大多仍使用 HTTP 頭部輸入的方式。由於規則通常都很長,導致每次頁面訪問,都會額外增加數百字節。

維護繁瑣

如果是通過 Web 服務開啓的,那麼每次調整策略,都得修改配置甚至重啓服務,很是麻煩。

兼容性不高

目前只有高版本的瀏覽器支持,而 IE 系列的則幾乎都沒能很好的支持。

如果某些攻擊只爭對低版本的瀏覽器,那麼很有可能出現大量遺漏。

模擬的 CSP

原理

事實上在 CSP 出現的好幾年前,就有一個能夠監控跨站資源的方案,下面就來分享下。

寫過 JS 的都知道,如果需要給大量元素監聽事件,無需對每個元素上都進行綁定,只要監聽它們的容器即可。當具體的事件冒泡到容器上,通過 event.target 即可獲知是哪個元素產生的。

腳本、圖片、框架等元素加載完成時,都會產生 onload 事件;而所有元素都位於『文檔』這個頂級容器。因此我們監聽 document 的 onload 事件,即可獲知所有加載資源的元素。

不過 onload 這個事件比較特殊,無法通過冒泡的方式來監聽。但在 DOM-3 標準模型裏,事件還有一個『捕獲』的概念,這也是爲什麼 addEventListener 有第三個參數的原因。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章