IT技(ji)術互動交(jiao)流(liu)平(ping)台

鸿福彩票官网

作者︰佚名  發(fa)布日期(qi)︰2020-02-23 15:29:29

 關于 XSS 怎(zen)樣形成、如何注入、能(neng)做什麼chu)?綰畏婪叮 qian)人已有無數的(de)探討,這里就(jiu)不再累述了。

幾乎每(mei)篇談(tan)論(lun) XSS 的(de)文章,結(jie)尾多(duo)少(shao)都會提(ti)到如何防止,然(ran)而大多(duo)萬變不離(li)其(qi)宗。要(yao)轉義什麼,要(yao)過濾什麼,不要(yao)忘了什麼之類的(de)。盡管都是眾所周知的(de)道lan)恚 XSS 漏洞十幾gai)昀醇負醮游粗卸瞎 環σ恍┐笸疽彩shi)常爆出(chu),小網站更是家常便飯。

而本文介紹的(de)則是另一種預防思路 —— 通過前(qian)端監控腳本,讓(rang)每(mei)一個用戶(hu)都參與漏洞的(de)監控和上報。

鸿福彩票官网

事lv)瞪希 兩jin)仍未有一勞(lao)永逸的(de)解決(jue)方案(an),要(yao)避(bi)免(mian)它依舊使用最古老的(de)土(tu)辦法(fa),逐個的(de)過濾。然(ran)而人總有疏忽的(de)時(shi)候(hou),每(mei)當產品迭代(dai)更新lv)shi),難免(mian)會遺(yi)漏一些新字段,導致漏洞被引入。

即使聖(sheng)人千慮也有一失,程序出(chu) BUG 完全可以理解,及時(shi)修復就(jiu)行(xing)。但令人費(fei)解的(de)是,問題出(chu)現到被發(fa)現,卻(que)要(yao)經過相當長的(de)時(shi)間(jian)。例如不久(jiu)前(qian)貼(tie)吧 XSS 蠕蟲腳本,直到大規模爆發(fa)後經用戶(hu)舉報,最終(zhong)才得知。其(qi)他(ta)網站大多(duo)也類似,直到白帽子們挖掘出(chu)漏洞,提(ti)交(jiao)到安全平(ping)台上,最終(zhong)廠商才被告知。若(ruo)遇到黑客私下留著這些漏洞慢慢利用,那只(zhi)能(neng)听天(tian)由(you)命了。

因此,要(yao)是能(neng)有一套(tao)實時(shi)的(de)預警系統,那就(jiu)更好了。即使無法(fa)阻止漏洞的(de)發(fa)生,但能(neng)在漏洞觸發(fa)的(de)第(di)一時(shi)間(jian)里,通知開發(fa)人員(yuan),即可在最短的(de)時(shi)間(jian)里修復,將損失降dang)階畹汀8魘礁餮de)應用層防火牆,也由(you)此產生。

不huai) 痛chuan)統的(de)系統漏洞不同,XSS 最終(zhong)是在用戶(hu)頁面中觸發(fa)的(de)。因此,我們不妨嘗(chang)試使用前(qian)端的(de)思路,進行(xing)在線防御。

鸿福彩票官网

先來假設一個有 BUG 的(de)後台,沒有很好處理用戶(hu)輸入的(de)數據,導致 XSS 能(neng)被注入到頁面︰

<imgsrc="{路徑}"/>

<imgsrc="{路徑"onload="alert(/xss/)}"/>

只(zhi)轉義尖括號,卻(que)忘了引號,是 XSS 里最為(wei)常見的(de)。攻擊者們可以提(ti)前(qian)關閉屬性,並添(tian)加一個極(ji)易觸發(fa)的(de)內聯事件,跨(kua)站腳本就(jiu)這樣被輕易執行(xing)了。

那麼,我們能(neng)否使用前(qian)端腳本來捕獲,甚至攔截呢?

鸿福彩票官网

最簡單的(de)辦法(fa),就(jiu)是qian)ba)頁面里所有元(yuan)素都掃描一遍,檢測那些 on 開頭的(de)內聯屬性,看看是不是存(cun)在異常︰

例如字符(fu)數非(fei)常多(duo),正常情況下這是很少(shao)出(chu)現的(de),但 XSS 為(wei)了躲避(bi)轉義有時(shi)會編碼的(de)很長;例如出(chu)現一些 XSS 經常使用的(de)關鍵字,但在實際產品里幾乎不會用到的(de)。這些都可以作為(wei)漏洞出(chu)現的(de)征兆,通知給開發(fa)人員(yuan)。

不huai) tu)辦法(fa)終(zhong)究存(cun)在很大的(de)局限性。在如今(jin)清一色的(de) AJAX 時(shi)代(dai),頁面元(yuan)素從來都不是固定的(de)。伴(ban)隨著用戶(hu)各種交(jiao)互,新內容隨時(shi)都可能(neng)動態添(tian)加進來chu)<詞夠懷啥ㄆqi)掃描一次,XSS 也bu)贍neng)在定時(shi)器的(de)間(jian)隔中觸發(fa),並銷毀自己,那樣永遠(yuan)都無法(fa)跟蹤到了。況且,頻(pin)繁的(de)掃描對性能(neng)影(ying)響(xiang)也是巨大的(de)。

如同早期(qi)的(de)安全軟件一樣,每(mei)隔幾秒掃描一次注冊表啟動項(xiang),不僅費(fei)性能(neng),而且對yuan)褚餿砑負醪黃 饔茫壞  蟺de)主動防御系統就(jiu)不同了,只(zhi)有在真正調用 API 時(shi)才進行(xing)分(fen)析,不通過則直接攔截,完全避(bi)免(mian)了定時(shi)器的(de)間(jian)隔遺(yi)漏。

因此,我們需(xu)要(yao)這種類似pin)de)延時(shi)策略 —— 僅在 XSS 即將觸發(fa)時(shi)對yun)浞fen)析,對不符(fu)合(he)策略的(de)元(yuan)素,進行(xing)攔截或(huo)者放行(xing),同時(shi)發(fa)送(song)報警到後台日志。

鸿福彩票官网

『主動防御』,這概(gai)念放在前(qian)端腳本里似乎有xing)┬酢5 荒遜fa)現,這僅僅是執行(xing)優(you)先級的(de)事而已 —— 只(zhi)要(yao)防御程序能(neng)運行(xing)在其(qi)他(ta)程序之前(qian),我們就(jiu)有了可進可退的(de)主動權。對于無比強大的(de) HTML5 和tu)榛huo)多(duo)變的(de) JavaScript,這些概(gai)念都可以yuan)煌孀 chu)來chu)/p>

繼續回到剛才討論(lun)的(de)內聯事件 XSS 上來chu)a href="http://www.it165.net/edu/ewl/" target="_blank" class="keylink">瀏覽(lan)器雖(sui)然(ran)沒提(ti)供可操(cao)控內聯事件的(de)接口,但內聯事件的(de)本質(zhi)仍是一個事件,無論(lun)怎(zen)樣變化都離(li)不開 DOM 事件模型。

扯到模型上面,一切即將迎刃而解。模型是解決(jue)問題的(de)最靠譜(pu)的(de)辦法(fa),尤rao)涫竅nbsp;DOM-3-Event 這種早已制定的(de)模型,其(qi)穩定性毋(wu)庸(yong)置(zhi)疑。

即便沒仔細閱讀官(guan)方文檔(dang),但凡(fan)做過網頁的(de)都知道,有個 addEventListener 的(de)接口,並取代(dai)了曾經一個古老的(de)叫 attachEvent 的(de)東西(xi)。盡管只(zhi)是新增了一個參數而已,但正是這個差別成了人們津津樂道的(de)話題。每(mei)當面試談(tan)到事件時(shi),總少(shao)不了考(kao)察下這個新參數的(de)用途。盡管在日常開發(fa)中很少(shao)用到它。

 

關于事件捕獲和冒泡(pao)的(de)細fu)冢 jiu)不多(duo)討論(lun)了。下面的(de)這段代(dai)碼,或(huo)許能(neng)激(ji)發(fa)你(ni)對『主動防御』的(de)遐想。

<button onclick="console.log('target')">CLICK ME</button>

<script>

   document.addEventListener('click',function(e {

       console.log('bubble');

   });

   document.addEventListener('click',function(e {

       console.log('capture');//e.stopImmediatePropagation();

   },true);

</script>

Run

盡管按鈕(niu)上直接ying)罅艘桓瞿諏 de)事件,但事件模型並不買(mai)賬,仍然(ran)得按標(biao)準的(de)流(liu)程tao)咭槐欏apture,target,bubble,模型就(jiu)是那樣固執chu)/p>

不huai) ba)那行(xing)注釋的(de)代(dai)碼恢復,結(jie)果就(jiu)只(zhi)剩(sheng) capture 了。這個簡單的(de)道lan)澩蠹葉濟靼祝 裁皇裁春媒饈偷de)。

但仔細揣摩下,這不就(jiu)是『主動防御』的(de)概(gai)念嗎?捕獲程序運行(xing)在內聯事件觸發(fa)之前(qian),並且完全有xin)neng)力(li)攔截之後的(de)調用。

上面的(de) Demo 只(zhi)是不假思索攔截了所有的(de)事件。如果我們再加一些策略判斷,或(huo)許就(jiu)更明朗了︰

<button onclick="console.log('xss')">

   CLICK ME

</button>

<script>

   document.addEventListener('click',function(e){

       console.log('bubble');

   });

   document.addEventListener('click',function(e){

       var element=e.target;

       var code=element.getAttribute('onclick');

       if(/xss/.test(code)){

           e.stopImmediatePropagation();

           alert('攔截可疑事件: '+code);

       }},true);

</script>

Run

我們先在捕獲階段掃描內聯事件字符(fu),若(ruo)是出(chu)現了『xss』這個關鍵字,後續的(de)事件就(jiu)被攔截了;換成其(qi)他(ta)字符(fu),仍然(ran)繼續執行(xing)。同理,我們還(huai)可以判斷字符(fu)長度是否過多(duo),以及an) 傅de)黑白名單正則。

怎(zen)麼樣,一個主動防御的(de)原型誕生了吧。

不huai) 廈嫻de)片段還(huai)有個小問題,就(jiu)是qian)ba)事件的(de)冒泡(pao)過程也給屏蔽了,而我們僅僅想攔截內聯事件而已。解決(jue)辦法(fa)也很簡單,把(ba) e.stopImmediatePropagation() 換成 element.onclick = null 就(jiu)可以了。

當然(ran),目前(qian)這只(zhi)能(neng)防護 onclick,而現zhi)抵杏刑 duo)的(de)內聯事件。鼠標(biao)、鍵盤、觸屏、網絡狀態等等,不同瀏覽(lan)器支持(chi)的(de)事件也不一樣,甚至還(huai)有私有事件,難道都要(yao)事先逐一列出(chu)並且都捕獲嗎?是的(de),可以yuan)疾痘瘢  槐厥孿榷劑諧chu)來chu)/p>

因為(wei)我們監听的(de)是 document 對象,瀏覽(lan)器所有xin)諏 錄級雜ψdocument.on*** 這類屬性,因此只(zhi)需(xu)運行(xing)時(shi)遍歷一下 document 對象,即可獲得所有的(de)事件名。

<img src="*"onerror="alert('xss')"/>

<script>

   functionhookEvent(eventName){

       document.addEventListener(eventName.substr(2),function(e){

       var element=e.target;

       if(element.nodeType!=Node.ELEMENT_NODE){

           return;

       }

       var code=element.getAttribute(eventName);

       if(code&&/xss/.test(code)){

           element[eventName]=null;

           alert('攔截可疑事件:',code);

       }},true);

   }

   console.time('耗時(shi)');

   for(varkindocument){

       if(/^on./.test(k)){

           //console.log('監控:', k);

           hookEvent(k);

       }}

   console.timeEnd('耗時(shi)');

</script>

Run

現在,無論(lun)頁面中xin)母鱸yuan)素觸發(fa)哪個內聯事件,都能(neng)預先被我們捕獲,並根據策略可進可退了。(不huai)OSX 10.9+ 的(de) Safari 瀏覽(lan)器無法(fa)枚舉出(chu) on 開頭的(de)屬性,可能(neng)是個 BUG 吧~)

鸿福彩票官网

現zhi)抵校 艘on 開頭這種內聯外(wai),還(huai)存(cun)在一些特殊形式。最常見的(de)就(jiu)是 javascript︰ 的(de)屬性,在一些歷史(shi)遺(yi)留的(de)非(fei)標(biao)準jian) lan)器中,飽受詬(gou)病(bing)。

例如曾經的(de) IE 瀏覽(lan)器就(jiu)支持(chi)zhong)庋de) URL︰

<img src="javascript︰alert('hello')">

<img src='vbscript:msgbox "hello"'>

這種zhi) 嚀tian)足的(de)設計(ji),曾導致過去無數的(de)論(lun)壇深(shen)受其(qi)害。

如今(jin)這種毫無意義的(de)過度設計(ji),早已被標(biao)準拋棄。除了某些小眾瀏覽(lan)器或(huo)許仍有遺(yi)留,可以參考(kao)這里。

不huai) 幸桓鍪褂錳乇鴯guang)泛(fan),以至如今(jin)標(biao)準仍有保(bao)留,那就(jiu)是︰

<ahref="javascript︰">

 

對于這類情況,我們就(jiu)得單獨對待,做其(qi)特殊處理︰

<a href="javascript︰alert(/xss/)">Click Me</a><

script>functionhookEvent(eventName){

   varisClick=(eventName=='onclick');

   document.addEventListener(eventName.substr(2),function(e){

       varel=e.target;

       if(el.nodeType!=Node.ELEMENT_NODE){

           return;

       }

       // ...

       // 掃描 <a href="javascript︰"> 的(de)腳本

       if(isClick&&el.tagName=='A'&&el.protocol=='javascript︰'){

           varcode=el.href.substr(11);

           if(/xss/.test(code)){

               el.href='javascript︰void(0)';

               alert('攔截可疑事件:',code);

           }}

       },true);

   }

   for(varkindocument){

       if(/^on./.test(k)){

           hookEvent(k);

       }

   }

</script>

Run

鸿福彩票官网

或(huo)許有xing)┤錄揮斜匾yao)捕獲,例如視頻(pin)播放、音量調節等,但就(jiu)算全都捕捉也耗不了多(duo)少(shao)時(shi)間(jian),基本都在 1ms 左右。

當然(ran),注冊事件本來就(jiu)花不了多(duo)少(shao)時(shi)間(jian),真正的(de)耗費(fei)都算在回調上了。盡管大多(duo)數事件觸發(fa)都不頻(pin)繁bao) 鍆wai)的(de)掃描可以忽律不計(ji)。但和鼠標(biao)移(yi)動相關的(de)事件那就(jiu)不容忽視了,因此得mei)kao)慮性能(neng)優(you)化。

顯然(ran),內聯事件代(dai)碼在運行(xing)過程中幾乎不可能(neng)發(fa)生變化。使用內聯事件大多(duo)為(wei)了簡單,如果還(huai)要(yao)在運行(xing)時(shi) setAttribute 去改(gai)變內聯代(dai)碼,完全就(jiu)是不可理喻的(de)。因此,我們只(zhi)需(xu)對某個元(yuan)素的(de)特定事件,掃描一次就(jiu)可以了。之後根據標(biao)志,即可直接跳過。

 

<div style="width:100%; height:100%; position:absolute; background: red" onmousemove="alert('xss')">

   <a href="javascript︰alert(/xss/)">Click Me</a>

</div>

<script>

   var mCheckMap = {};

   var mCheckID = 0;

   function hookEvent(eventName, eventID) {

       var isClick = (eventName == 'onclick');

       function scanElement(el) {

           //

           // 跳過已掃描的(de)事件

           //

           var flag = el['_k'];

           if (!flag) {

               flag = el['_k'] = ++mCheckID;

           }

           var hash = (flag << 8) eventID;

           if (hash in mCheckMap) {

               return;

           }

           mCheckMap[hash] = true;

           // 非(fei)元(yuan)素節點

           if (el.nodeType != Node.ELEMENT_NODE) {

               return;

           }

           // 掃描內聯代(dai)碼

           var code;

           if (el[eventName]) {

               code = el.getAttribute(eventName);

               if (code && /xss/.test(code)) {

                   el[eventName] = null;

                   alert('攔截可疑事件:' + code);

               }

           }

           // 掃描 <a href="javascript︰"> 的(de)腳本

           if (isClick && el.tagName == 'A' && el.protocol == 'javascript︰') {

               var code = el.href.substr(11);

               if (/xss/.test(code)) {

                   el.href = 'javascript︰void(0)';

                   alert('攔截可疑事件:' + code);

               }

           }

           // 掃描上級元(yuan)素

           scanElement(el.parentNode);

       }

       document.addEventListener(eventName.substr(2), function(e) {

           scanElement(e.target);

       }, true);

   }

   var i = 0;

   for (var k in document) {

       if (/^on./.test(k)) {

           hookEvent(k, i++);

       }

   }

</script>

 

Run

這樣,之後的(de)掃描僅僅是檢測一下,目標(biao)對象是否存(cun)在標(biao)記(ji)而已。即使瘋狂(kuang)晃動鼠標(biao),CPU 使用率(lv)也都忽略不計(ji)了。

與之前(qian)不同的(de)是,這里我們增加了一個叫 scanElement 的(de)函(han)數,並遞歸掃描上級元(yuan)素。之所以這麼做,還(huai)是因為(wei)和冒泡(pao)有關。即使當前(qian)元(yuan)素不存(cun)在內聯事件,但並不代(dai)表上級容器也沒有。因此,我們將元(yuan)素自身及所有上級 DOM 都掃描一遍,以防lao)蛞弧Syou)于掃描過的(de)會有標(biao)記(ji),所以並不會增加性能(neng)消耗。

到此,在 XSS 內聯事件這塊,我們已實現主動防御。

對于有著大量字符(fu),或(huo)者出(chu)現類似 String.fromCharCode,$.getScript 這類典型 XSS 代(dai)碼的(de),完全可以將其(qi)攔截;發(fa)現有 alert(/xss/),alert(123) 這些測試代(dai)碼,可以暫(zan)時(shi)放行(xing),並將日志發(fa)送(song)到後台,確定是否能(neng)夠復現。

如果復現,說明已有人發(fa)現 XSS 並成功注入了,但還(huai)沒大規模開始利用。程序猿們趕緊第(di)一時(shi)間(jian)修 BUG 吧,讓(rang)黑客忙活(huo)一陣子後發(fa)現漏洞已經修復了︰)

鸿福彩票官网

但是,光靠代(dai)碼字符(fu)串(chuan)來判斷,還(huai)是會有疏漏的(de)。尤rao)涫嗆誑兔侵 烙姓餉錘 嬉獯cun)在,會更加小心(xin)了。把(ba)代(dai)碼轉義用以yuan)惚bi)關鍵字,並將字符(fu)存(cun)儲在其(qi)他(ta)地方,以yuan)愎?燃觳猓 純賞耆 rao)過我們的(de)監控了︰

<imgsrc="*"onerror="window['ev'+'al'](this.align)"align="alert('a mass of code...')">

因此,我們不僅需(xu)要(yao)分(fen)析關鍵字。在回調執行(xing)時(shi),還(huai)需(xu)監控 eval、setTimeout('...') 等這類能(neng)解析代(dai)碼的(de)函(han)數被調用。

不huai)  2換嶙?  duo)的(de)代(dai)碼,而是直接引入一個外(wai)部(bu)腳本,既簡單又靠譜(pu),並且能(neng)實時(shi)修改(gai)攻擊內容︰

<imgsrc="*"onerror="$['get'+'Script'](...)">

 

Tag標(biao)簽︰前(qian)端  防火牆  事件  
  • 鸿福彩票官网

About IT165 - 廣(guang)告服務 - 隱私聲明 - 版權申明 - 免(mian)責條款 - 網站地圖(tu) - 三分pk10官网網友投(tou)稿 - 聯系方式
本站內容來自于互聯網,僅供用于網絡技(ji)術學習,學習中請遵循相關法(fa)律法(fa)規
鸿福彩票官网 | 下一页