打造雙劍合璧的 XSS 前端防火牆

發表於2015-09-30

前言

深入接觸 xss 注入是從排查業務的廣告注入開始,以前對 xss 注入片面認為是頁面輸入的安全校驗漏洞導致一系列的問題,通過對 zjcqoo 的《XSS 前端防火牆》系列文章,認識到自己其實對 XSS 注入的認識還真是半桶水。

搗蛋的運營商

由於 xss 注入的範圍太廣,本文僅對閘道器劫持這一方面的 XSS 注入進行討論。
這裡讀者有個小小的疑問,為什麼我要選閘道器劫持進行討論?因為閘道器劫持可以大面積範圍進行有效控制。

曾經,有這樣一道風靡前端的面試題(當然我也現場筆試過):當你在瀏覽器位址列輸入一個URL後回車,將會發生的事情?其實本文不關心請求發到服務端的具體過程,但是我關心的時,服務端響應輸出的文件,可能會在哪些環節被注入廣告?手機、路由器閘道器、網路代理,還有一級運營商閘道器等等。所以,無論如何,任何網頁都得經過運營商閘道器,而且最調(zui)皮(da)搗(e)蛋(ji)的,就是通過運營商閘道器。

另外, 也提醒大家,如果手機安裝了一些上網加速軟體、網路代理軟體或設定網路代理 IP,會有安全風險,也包括公共場所/商家的免費 WIFI。

前端防火牆的實踐

經過近一段時間通過對 zjcqoo 的《XSS 前端防火牆》六板斧的反覆琢磨理解,基本上防禦措施可以歸為兩大類:一種是從協議上遮蔽,一種是從前端程式碼層面進行攔截移除。通過 zjcqoo 提出的幾種注入防禦方式,進行幾個月的實踐觀察,對廣告注入方式大概可以歸為兩種:完全靜態注入、先靜態注入後動態修改(建立)。
1. 完全靜態注入
完全內聯 js、css、和 dom,不管是 body 內外,甚是噁心,而且如果是在監控指令碼前面注入的,還可以搶先執行,造成防禦不起作用。注入的 DOM 也無法清除。
2. 先靜態注入後動態修改
這種可以分為幾種:一種是非同步請求介面資料再生成 DOM 注入,一種是修改 iframe 源地址進行引入,另外一種是修改 script 源地址,請求執行 js 再非同步獲取資料或生成 DOM。

監控資料觀察分析

對 zjcqoo 提出的幾種防禦方式的實踐,前一個月主要是花在優化檢測指令碼和增加白名單過濾髒資料方面,因為這塊事情只能利用業餘時間來搞,所以拖的時間有點久。白名單這塊的確是比較繁瑣,很多人以為分析下已知的域名就 ok 了,其實不然,雲龍在這篇 iframe 黑魔法就提到移動端 Native 與 web 的通訊機制,所以在各種 APP 上,會有各種 iframe 的注入,而且是各種五花八門的協議地址,也包括 chrome。

監控拿到的資料很多,但是,由於對整個廣告注入黑產行業的不熟悉,所以,有必要藉助 google 進行查詢研究,發現,運營商大大地狡猾,他們自己只會注入自己業務的廣告,如 4G 免費換卡/送流量/送話費,但是商業廣告這塊蛋糕他們會拱手讓人?答案是不可能,他們會勾結其他廣告代理公司,利用他們的廣告分發平臺(運營商被美名為廣告系統平臺提供商)進行廣告投放然後分成…

對於使用者投訴,他們一般都是認錯,然後對這個使用者加白名單,但是他們對其他使用者還是繼續作惡。對於企業方面的投訴,如果影響到他們的域名,如果你沒有確鑿的證據,他們就會用各種藉口擺脫自己的責任,如使用者手機中毒等等,如果你有確鑿的證據,還得是他們運營商自己的域名或者 IP,否則他們也無法處理。他們還是一樣的藉口,使用者手機中毒等等。

除非你把運營商的域名或 IP 監控資料列給他看,他才轉變態度認錯,但是這僅僅也是之前我們提到的流量話費廣告,對於第三方廣告代理商的廣告,還是沒法解決,這些第三方廣告代理商有廣告家、花生米、XX 傳媒等等中小型廣告商,當然也不排除,有的是“個體戶廣告商”。

從另一方面來看,由於使用的是古老的 http 協議,這種明文傳輸的協議,html 內容可以被運營商一清二楚地記錄下來,頁面關鍵字、訪問時間、地域等使用者標籤都可以進行採集,說到這,你可能已經明白了一個事(隱私侵犯已經見怪不怪了)——大資料分析+個性化推薦,在 google 一查,運營商還真有部署類似於 iPush 網路廣告定向直投這樣的系統,而且廣告點選率也出奇的高,不排除會定向推送一些偏黃色的圖片或遊戲。

另外,資料分析中發現一些百度統計的介面請求,也在一些 js 樣本中發現百度統計地址,猜測很有可能是這種廣告平臺利用百度統計系統做資料分析,如定向投放使用者 PV 統計,廣告效果統計等等。
監控資料分析也扯這麼多了,我們還是回來看怎麼做防禦措施吧!

防禦措施介紹

全站 HTTPS + HSTS

開啟 HTTPS,可以加強資料保密性、完整性、和身份校驗,而 HSTS (全稱 HTTP Strict Transport Security)可以保證瀏覽器在很長時間裡都會只用 HTTPS 訪問站點,這是該防禦方式的優點。但是,缺點和缺陷也不可忽略。

網際網路全站HTTPS的時代已經到來 一文已有詳細的分析,加密解密的效能損耗在服務端的損耗和網路互動的損耗,但是移動端瀏覽器和 webview 的相容性支援卻是個問題,比如 Android webview 需要韌體4.4以上才支援,iOS safari 8 以上也才支援,而 UC 瀏覽器目前還不支援。

而目前推動團隊所有業務支援 HTTPS 難度也是相當高,部分 302 重定向也有可能存在 SSLStrip,更何況 UC 瀏覽器還不支援這個協議,很容易通過 SSLStrip 進行劫持利用,雖然運營商大部分情況下不會這麼幹,但是我還是堅定懷疑他們的節操。由於我國寬頻網路的基本國情,短時間指望速度提升基本上不可能的,就算總理一句話,但哪個運營商不想賺錢?所以,業務效能的下降和業務安全,需要進行權衡利弊。

Content Security Policy(簡稱 CSP)

CSP 內容安全策略,屬於一種瀏覽器安全策略,以可信白名單作機制,來限制網站中是否可以包含某來源內容。相容性支援同樣是個問題,比如 Android webview 需要韌體4.4以上才支援,iOS safari 6 以上支援,幸運的是 UC 瀏覽器目前支援 1.0 策略版本,具體可以到 CANIUSE 瞭解。目前對 CSP 的使用僅有不到兩週的經驗而已,下面簡單說說其優缺點。

缺點:

  1. CSP 規範也比較累贅,每種型別需要重新配置一份,預設配置不能繼承,只能替換,這樣會導致整個 header 內容會大大增加。
  2. 如果業務中有爬蟲是抓取了外部圖片的話,那麼 img 配置要麼需要列舉各種域名,要麼就信任所有域名。
  3. 3. 移動端 web app 頁面,如果有存在 Native 與 web 的通訊,那麼 iframe 配置只能信任所有域名和協議了。
  4. 4. 一些業務場景導致無法排除內聯 script 的情況,所以只能開啟 unsafe-inline
  5. 5. 一些庫仍在使用 eval,所以避免誤傷,也只能開啟 unsafe-eval
  6. 6. 由於 iframe 信任所有域名和協議,而 unsafe-inline 開啟,使得整個防禦效果大大降低

優點:

  1. 通過 connect/script 配置,我們可以控制哪些 外部域名非同步請求可以發出,這無疑是大大的福音,即使內聯 script 被注入,非同步請求仍然發不出,這樣一來,除非攻擊者把所有的 js 都內聯進來,否則注入的功能也執行不了,也無法統計效果如何。
  2. 通過 reportUri 可以統計到攻擊型別和 PV,只不過這個介面的設計不能自定義,上報的內容大部分都是雞肋。
  3. object/media 配置可以遮蔽一些外部多媒體的載入,不過這對於視訊播放類的業務,也會誤傷到。
  4. 目前 UC 瀏覽器 Android 版本的客戶端和 web 端通訊機制都是採用標準的 addJavascriptInterface 注入方式,而 iPhone 版本已將 iframe 通訊方式改成 ajax 方式(與頁面同域,10.5 全部改造完成),如果是隻依賴 UC 瀏覽器的業務,可以大膽放心使用,如果是需要依賴於第三方平臺,建議先開啟 reportOnly,將一些本地協議加入白名單,再完全開啟防禦。

總的來說吧,單靠 CSP 單打獨鬥顯然是不行,即使完全開啟所有策略,也不能完成消除注入攻擊,但是作為縱深防禦體系中的一道封鎖防線,價值也是相當有用的。

前端防火牆攔截

前端防火牆顯然適合作為第一道防線進行設計,可以預先對一些注入的內聯 js 程式碼、script/iframe 源引用進行移除,同時對 script/iframe 源地址修改做監控移除。
基本設計邏輯大概如下:

詳細的實現邏輯,參考zjcqoo 的《XSS 前端防火牆》系列文章。

缺點:

  1. 如果是在監控指令碼執行前,注入的指令碼已經執行,顯然後知後覺無法起防禦作用了。
  2. 一些 DOM 的注入顯然無能為力。

優點:

  1. 可以針對 iframe 做一些自定義的過濾規則,防止對本地通訊誤傷。
  2. 可以收集到一些注入行為資料進行分析。

雙劍合璧

即使是單純的 DOM 注入,顯然無法滿足更高階功能的使用,也會使運營商的廣告分發平臺效果大打折扣。如果單獨其中一種方式進行使用,也只是發揮了一招一式的半成功力,如果是雙手互搏,那也可以發揮成倍的功力。

而前端防火牆再加上 CSP 安全策略,雙劍合璧,則可以大大降低廣告注入帶來的負面效果,重則造成廣告程式碼嚴重癱瘓無法執行:在監控指令碼後注入廣告指令碼,基本上可以被前端防火牆封殺殆盡,即使有漏網之魚,也會被 CSP 進行追殺,不死也殘。

即使在監控指令碼執行前注入,通過 CSP content-src 策略,可以攔截白名單域名列表外的介面請求,使得廣告程式碼的非同步請求能力被封殺,script-src 策略,也可以封殺指令碼外鏈的一些外部請求,進一步封殺非同步指令碼引用,frame-src 策略無論先後建立的 iframe,一律照殺。

僥倖者躲過了初一,卻躲不過十五,前端防火牆拍馬趕到,照樣封殺無誤,唯一的路徑只有注入 DOM 這一方式,別忘了,只要開啟 img-src 策略配置,廣告程式碼只剩下文字鏈。雖然是一個文字鏈廣告,但點選率又能高到哪去呢?

如果你是 node 派系,小弟附上《辟邪劍譜》 helmet 一本,如果你的業務有涉及到 UCBrowser,更有《辟邪劍譜之 UC 版》helmet-csp-uc 。

所謂道高一尺魔高一丈,既然我們有高效的防禦措施,相信他們不久也會探索出反防禦方式,如此,我們也需要和這幫人鬥智鬥勇,一直等到 HTTP/2 規範的正式落地。

相關文章