摘要:我們通過事件捕獲機(jī)制,將其拿下,從而監(jiān)控文檔級(jí)別的全局事件。我們也可同時(shí)將其捕獲,跟蹤那些暫時(shí)不可用的跨站資源。不過本文的主題已經(jīng)說了,只是監(jiān)控跨站資源而已,并不攔截。轉(zhuǎn)自利用事件監(jiān)控跨站資源
說到跨站資源監(jiān)控,首先會(huì)聯(lián)想到『Content Security Policy』。既然 CSP 好用,我們何必自己再搞一套呢。那就先來吐槽下 CSP 的缺陷。
目前的 CSP 日志不詳細(xì)用過 CSP 的都很郁悶,上報(bào)的只有違規(guī)的站點(diǎn)名,卻沒有具體路徑。這是缺陷,還是特意的設(shè)計(jì)?
顯然,CSP 是為安全定制的,里面的規(guī)范自然要嚴(yán)格制定,否則就會(huì)帶來新的安全問題。如果支持詳細(xì)路徑的上報(bào),那又會(huì)引出什么問題?
由于 CSP 會(huì)上報(bào)所有的請(qǐng)求,甚至包括重定向的,因此可以用來探測重定向后的地址。假如已登錄的用戶訪問 login.xx.com 會(huì)重定向到 xx.com/username,那么攻擊者設(shè)計(jì)一個(gè)只允許重定向前的規(guī)則的頁面,用戶訪問后,重定向后的 URL 就會(huì)當(dāng)做違規(guī)地址上報(bào)給攻擊者,這其中就包括了用戶名。
如果支持詳細(xì)路徑的上報(bào),這簡直就是災(zāi)難,就用來探測的用戶隱私信息了。事實(shí)上目前只上報(bào)主機(jī)名,都能進(jìn)行一些利用,例如這篇 Using Content-Security-Policy for Evil。
不過新的規(guī)范總是在改進(jìn),未來也許只上報(bào)重定向前的 URL。但在這之前,我們只能接受這些雞肋的上報(bào)日志。
規(guī)則不靈活CSP 目前只支持白名單列表,這多少有些死板。
更糟的是,不同規(guī)則之間無法繼承和共享。例如默認(rèn)有個(gè) default-src 規(guī)則,但其他的規(guī)則會(huì)覆蓋它,而不是繼承它。這就導(dǎo)致各個(gè)規(guī)則之間,出現(xiàn)很多的重復(fù),使得整個(gè)字符串變的冗長。
無法和頁面交互CSP 的監(jiān)控和上報(bào),是在瀏覽器后臺(tái)自動(dòng)處理的,沒有提供一個(gè)事件供頁面進(jìn)行交互。
這樣就只能使用統(tǒng)一方式強(qiáng)制處理了,而無法交給頁面腳本,更好的來自定義處理。
上報(bào)方式不可控如果處理方式有多種選擇,那么統(tǒng)一處理也無可厚非。
但事實(shí)上 CSP 的上報(bào)方式及格式,沒有任何可選余地。只能使用 POST + JSON 的方式提交,并且其中的字段十分累贅,甚至把規(guī)則里的白名單列表也發(fā)上來了。
此外,也無法設(shè)定一個(gè)緩存時(shí)間,控制重復(fù)上報(bào)的間隔。在配置白名單遺漏時(shí),會(huì)出現(xiàn)大量的誤報(bào),嚴(yán)重消耗資源。
浪費(fèi)帶寬在較新的 Chrome 里,能夠使用 meta 標(biāo)簽在前端頁面定義 CSP 規(guī)則,但其他瀏覽器目前仍不支持。
為了能夠統(tǒng)一,大多仍使用 HTTP 頭部輸入的方式。由于規(guī)則通常都很長,導(dǎo)致每次頁面訪問,都會(huì)額外增加數(shù)百字節(jié)。
維護(hù)繁瑣如果是通過 Web 服務(wù)開啟的,那么每次調(diào)整策略,都得修改配置甚至重啟服務(wù),很是麻煩。
兼容性不高目前只有高版本的瀏覽器支持,而 IE 系列的則幾乎都沒能很好的支持。
如果某些攻擊只爭對(duì)低版本的瀏覽器,那么很有可能出現(xiàn)大量遺漏。
模擬的 CSP 原理事實(shí)上在 CSP 出現(xiàn)的好幾年前,就有一個(gè)能夠監(jiān)控跨站資源的方案,下面就來分享下。
寫過 JS 的都知道,如果需要給大量元素監(jiān)聽事件,無需對(duì)每個(gè)元素上都進(jìn)行綁定,只要監(jiān)聽它們的容器即可。當(dāng)具體的事件冒泡到容器上,通過 event.target 即可獲知是哪個(gè)元素產(chǎn)生的。
腳本、圖片、框架等元素加載完成時(shí),都會(huì)產(chǎn)生 onload 事件;而所有元素都位于『文檔』這個(gè)頂級(jí)容器。因此我們監(jiān)聽 document 的 onload 事件,即可獲知所有加載資源的元素。
不過 onload 這個(gè)事件比較特殊,無法通過冒泡的方式來監(jiān)聽。但在 DOM-3 標(biāo)準(zhǔn)模型里,事件還有一個(gè)『捕獲』的概念,這也是為什么 addEventListener 有第三個(gè)參數(shù)的原因。
我們通過事件捕獲機(jī)制,將其拿下,從而監(jiān)控文檔級(jí)別的全局 onload 事件。
類似的,如果資源加載失敗,會(huì)觸發(fā) onerror 事件。我們也可同時(shí)將其捕獲,跟蹤那些暫時(shí)不可用的跨站資源。
優(yōu)勢通過腳本的方式,就可以更靈活的處理問題了。規(guī)則的黑白名單,上報(bào)方式、格式等等,都可以自己來定義。最重要的是,我們能夠獲得詳細(xì)的違規(guī) URL 了!
相比后端配置,前端腳本更新維護(hù)起來容易的多。而且得益于瀏覽器緩存,無需每次更新配置,節(jié)省很多資源。
增強(qiáng)也許你已經(jīng)發(fā)現(xiàn)了,這只能實(shí)現(xiàn) CSP 的 Report-Only 功能,根本無法進(jìn)行攔截。而且其他的內(nèi)聯(lián)事件、網(wǎng)絡(luò)通信等也沒有涉及。
不過本文的主題已經(jīng)說了,只是監(jiān)控跨站資源而已,并不攔截。事實(shí)上,如果能夠做到及時(shí)發(fā)現(xiàn)問題,就很不錯(cuò)了。
如果非得通過 JS 來實(shí)現(xiàn)攔截功能,可以參考之前的『XSS 前端防火墻系列』:
內(nèi)聯(lián)事件攔截
跨站資源攔截
網(wǎng)絡(luò)通信攔截
雖然可以更嚴(yán)格的防護(hù),但實(shí)現(xiàn)起來更臃腫,性能開銷也更大。要是攔截了正常的業(yè)務(wù)功能,造成的損失會(huì)更大。
而使用如何這個(gè)小技巧,只需幾行代碼即可實(shí)現(xiàn),性能消耗忽略不計(jì)。
缺陷當(dāng)然,那么簡單的方案肯定無法全面。
由于我們只監(jiān)聽文檔容器,有些還未加入到文檔的元素產(chǎn)生的事件,我們就無法捕獲到了。最典型的就是:
new Image().src = "..."
雖然創(chuàng)建的 HTMLImageElement 對(duì)象具有 onload 事件,但是此時(shí)還只是一個(gè)離屏元素,事件就無法對(duì)外傳播了。
如果非得解決,只能通過函數(shù)鉤子的方式監(jiān)控 URL。
此外,IE9 以下的瀏覽器不支持 DOM-3,而 attachEvent 是無法設(shè)置捕獲的,因此我們還需一個(gè)后備方案。畢竟國內(nèi)低版本 IE 用戶仍有不少,即使能實(shí)現(xiàn)部分功能,也勝于無。
后備事實(shí)上,即使主流瀏覽器,有些特殊元素并沒有 onload 事件,例如 Flash 插件。
為了彌補(bǔ)這些不足,同時(shí)盡可能保持簡單高效,我們使用定時(shí)輪詢的方式,對(duì)特定元素進(jìn)行掃描。這里使用一個(gè)大家都知道,但未必都清楚的方法:document.getElementsByTagName。
這個(gè)功能都知道,但返回的類型或許很少琢磨。他返回的并不是一個(gè) Array,也不是 NodeList,而是 HTMLCollection。
在 W3C 規(guī)范描述中,有一個(gè)顯眼的詞 『live』,已經(jīng)道出了這個(gè)接口的獨(dú)特之處——它是一個(gè)動(dòng)態(tài)的集合,能隨著容器內(nèi)元素的增減而變化。
因此,我們事先映射出文檔容器內(nèi)的元素,之后即可隨時(shí)查詢集合了。
除了 SCRIPT,我們還可以監(jiān)控所有存在風(fēng)險(xiǎn)隱患的元素,例如:EMBED,OBJECT,IFRAME 等等。這樣即使是低版本的 IE 用戶,也能參與預(yù)警上報(bào)了,比起完全沒有好的多。
當(dāng)然,這種簡單方法也很容易被繞過。如果腳本刪除了自身元素,那么我們就無法跟蹤到了。而腳本一旦運(yùn)行就已在內(nèi)存里,即使元素節(jié)點(diǎn)被移除,仍然能繼續(xù)運(yùn)行。
不過,對(duì)于一般的情況也足夠應(yīng)對(duì)了。通常運(yùn)行商的廣告劫持,大多都很落后。即使要進(jìn)行后期對(duì)抗,也可以利用之前的前端防火墻,使用嚴(yán)格的方案。
擴(kuò)展信息見過 CSP 日志的大多都會(huì)很困惑,出現(xiàn)的這些違規(guī)資源,究竟位于頁面何處。由于沒有確切的細(xì)節(jié),給排查工作帶來很大困難。
畢竟,絕大多數(shù)的上報(bào)問題,都是無法復(fù)現(xiàn)的。它們要么是運(yùn)行商的廣告,或者是瀏覽器插件。難很通過這些日志,來定位問題所在。
既然如今使用自己的腳本來實(shí)現(xiàn),理應(yīng)帶上一些有意義的信息。除了資源類型和詳細(xì) URL,我們還需要一個(gè)能夠定位問題所在的參數(shù)——DOM 路徑。
將每層元素的 #id 和 .class 跟隨標(biāo)簽名,得到一個(gè)標(biāo)準(zhǔn)的 CSS 選擇器。通過它,即可非常容易的定位到違規(guī)元素,同時(shí)也能用于統(tǒng)計(jì)和分析。
例如出現(xiàn)頂級(jí)元素就是 SCRIPT 的,顯然這是一個(gè)被插入到 之外的腳本,很有可能就是運(yùn)營商注入的廣告腳本。
例如出現(xiàn) HTML > BODY > ... > DIV.editor-post > SCRIPT 這樣帖子容器里的腳本,那么極有可能是出現(xiàn) XSS 了。正常情況下,用戶內(nèi)容區(qū)域并不會(huì)出現(xiàn)腳本元素。
通過詳細(xì)的上報(bào)日志不斷學(xué)習(xí),后端即可越來越精準(zhǔn)的分析出問題所在。
而這些,目前的 CSP 難以實(shí)現(xiàn)。
上報(bào)方式吸取 CSP 報(bào)告的不足之處,我們使用更靈活的方式。
對(duì)于運(yùn)營商廣告那樣的跨站資源,反復(fù)上報(bào)同樣的信息,是毫無意義的,只會(huì)浪費(fèi)帶寬資源。對(duì)于同一類警告,一定時(shí)間內(nèi)上報(bào)一次就后夠了。
利用 URL、DOM 路徑等信息,可以更容易的將日志進(jìn)行客戶端去重。通過本地存儲(chǔ)的記錄,就不必每次都上報(bào)了,在本地記錄違規(guī)的次數(shù)即可。
對(duì)于不嚴(yán)重的警告,本地也可以累計(jì)到一定的數(shù)量再上報(bào)。這樣多條日志一次發(fā)送,即可大幅減輕后端壓力。甚至還可以考慮壓縮內(nèi)容,節(jié)省網(wǎng)絡(luò)帶寬。
只有讓前端進(jìn)行負(fù)載維護(hù),才不至于大規(guī)模部署的場合下,接收端被海量的誤報(bào)日志拖垮。
總結(jié)盡管 CSP 的初衷很美好,但到如今,仍只是能用,并沒有做到好用。因此,實(shí)際面臨的問題,還是得靠自己來解決。
當(dāng)然,標(biāo)準(zhǔn)的制定本來就是受益于大眾的,我們也希望 CSP 標(biāo)準(zhǔn)能發(fā)展的越來越好用。
轉(zhuǎn)自:利用 onload 事件監(jiān)控跨站資源
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85515.html
摘要:而第一種方法只能判斷引用類型,不能判斷值類型,因?yàn)橹殿愋蜎]有對(duì)應(yīng)的構(gòu)造函數(shù)描述一個(gè)對(duì)象的過程生成一個(gè)新的空對(duì)象指向這個(gè)新對(duì)象執(zhí)行構(gòu)造函數(shù)中的代碼,即對(duì)賦值將新對(duì)象的屬性指向構(gòu)造函數(shù)的屬性返回,即得到新對(duì)象。 最近在在看前端面試教程,這篇文章里大部分是看視頻的過程中自己遇到的不清楚的知識(shí)點(diǎn),內(nèi)容很簡單,只是起到一個(gè)梳理作用。有些地方也根據(jù)自己的理解在作者的基礎(chǔ)上加了點(diǎn)東西,如有錯(cuò)誤,歡迎...
摘要:三攻擊分類反射型又稱為非持久性跨站點(diǎn)腳本攻擊,它是最常見的類型的。存儲(chǔ)型又稱為持久型跨站點(diǎn)腳本,它一般發(fā)生在攻擊向量一般指攻擊代碼存儲(chǔ)在網(wǎng)站數(shù)據(jù)庫,當(dāng)一個(gè)頁面被用戶打開的時(shí)候執(zhí)行。例如,當(dāng)錯(cuò)誤,就會(huì)執(zhí)行事件利用跨站。 一、簡介 XSS(cross site script)是指惡意攻擊者利用網(wǎng)站沒有對(duì)用戶提交數(shù)據(jù)進(jìn)行轉(zhuǎn)義處理或者過濾不足的缺點(diǎn),進(jìn)而添加一些代碼,嵌入到web頁面中去。使別...
摘要:三攻擊分類反射型又稱為非持久性跨站點(diǎn)腳本攻擊,它是最常見的類型的。存儲(chǔ)型又稱為持久型跨站點(diǎn)腳本,它一般發(fā)生在攻擊向量一般指攻擊代碼存儲(chǔ)在網(wǎng)站數(shù)據(jù)庫,當(dāng)一個(gè)頁面被用戶打開的時(shí)候執(zhí)行。例如,當(dāng)錯(cuò)誤,就會(huì)執(zhí)行事件利用跨站。 一、簡介 XSS(cross site script)是指惡意攻擊者利用網(wǎng)站沒有對(duì)用戶提交數(shù)據(jù)進(jìn)行轉(zhuǎn)義處理或者過濾不足的缺點(diǎn),進(jìn)而添加一些代碼,嵌入到web頁面中去。使別...
摘要:通常編寫過濾器驗(yàn)證用戶輸入時(shí),過濾器應(yīng)該是基于白名單已知的安全結(jié)構(gòu)配置編寫,允許白名單通過,不允許其他輸入而基于黑名單已知的不安全結(jié)構(gòu)配置編寫,即允許除了黑名單之外的所有輸入,是不安全的,因?yàn)檫€有許多未知的不安全事物。原文鏈接應(yīng)用安全 XSS (Cross-site scripting) XSS,跨站腳本攻擊。 SQL注入(SQL injection) 在接受不確定輸入內(nèi)容(如第三方站...
摘要:建議后端替換前端執(zhí)行效率低,影響性能跨站請(qǐng)求偽造示例你已登錄一個(gè)購物網(wǎng)站,正在瀏覽商品假如該網(wǎng)站付費(fèi)接口是但是沒有任何驗(yàn)證然后你收到一封郵件,隱藏著你查看郵件的時(shí)候,就已經(jīng)悄悄的付費(fèi)購買了解決辦法增加驗(yàn)證流程,如驗(yàn)證指紋輸入密碼短信驗(yàn)證碼 頁面加載 加載資源的形式 1.輸入url或跳轉(zhuǎn)頁面加載html2.加載html中的靜態(tài)資源 加載一個(gè)資源的過程 1.瀏覽器根據(jù)DNS服務(wù)器得到域名的...
閱讀 3093·2021-09-22 15:20
閱讀 2610·2019-08-30 15:54
閱讀 1975·2019-08-30 14:06
閱讀 3123·2019-08-30 13:05
閱讀 2467·2019-08-29 18:36
閱讀 580·2019-08-29 15:10
閱讀 533·2019-08-29 11:17
閱讀 833·2019-08-28 18:11