溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

web安全之XSS

發(fā)布時(shí)間:2020-06-20 11:05:08 來(lái)源:網(wǎng)絡(luò) 閱讀:836 作者:TsingCall 欄目:安全技術(shù)

一、瀏覽器安全

1、同源策略(SOP

     在瀏覽器中,<script>、<img>、<iframe><link>等標(biāo)簽都可以跨域加載資源,而不受同源限制。這些帶src屬性的標(biāo)簽每次加載時(shí),實(shí)際上是有瀏覽器發(fā)起了一次GET請(qǐng)求。不同于XMLHttpRequest(通過(guò)目標(biāo)域返回的HTTP"Access-Control-Allow-Origin:*  *允許訪問(wèn)自己的域"來(lái)授權(quán)是否允許跨域訪問(wèn),因?yàn)?/span>HTTP頭對(duì)JavaScript來(lái)說(shuō)一般是無(wú)法控制的)的是,通過(guò)src屬性加載的資源,瀏覽器限制了JavaScript的權(quán)限,使其不能讀、寫(xiě)返回的內(nèi)容。

2、瀏覽器沙箱(Sandbox

3、惡意網(wǎng)站攔截

 

二、跨腳本***(XSS

2.1 XSS***類(lèi)型

2.1.1、反射型XSS

     通過(guò)用戶輸入的數(shù)據(jù)反射給瀏覽器,反射型XSS也叫非持久型XSS”Non-persistent XSS

 

     假設(shè)一個(gè)頁(yè)面把用戶輸入的參數(shù)直接輸出的頁(yè)面上:

<?php

   $input = $_GET["param"];
   echo "<div>".$input."<div>";
?>

    正常情況下,用戶想param提交的數(shù)據(jù)會(huì)展示在頁(yè)面里,如:

http://www.a.com/test.php?param=這是一個(gè)測(cè)試;

    此時(shí)查看源碼:

<div> 這是一個(gè)測(cè)試 </div>

    但如果提交一段HTML代碼:

http://www.a.com/test.php?param=<script>alert(/xss)</script>;

    再查看源碼:

<div> <script>alert(/xss)</script>; </div>

2.1.2、存儲(chǔ)型XSS

    ***會(huì)把用戶的數(shù)據(jù)存儲(chǔ)在服務(wù)器端。

    比較常見(jiàn)的場(chǎng)景是:***寫(xiě)了一篇包含有惡意JavaScript代碼的博客文章,只要用戶訪問(wèn)改文章,就會(huì)在他們的瀏覽器中執(zhí)行這段惡意代碼,***會(huì)把惡意代碼保存到服務(wù)器端。所以這種方式也叫持久型XSSPersistent XSS)。

2.1.3DOM Based XSS

    通過(guò)修改頁(yè)面的DOM節(jié)點(diǎn)形成XSS,稱(chēng)之為DOM Based XSS

    代碼如例:

<script>
function test() {
   var str = document.getElementById("text").value;
   document.getElementById("t").innerHTML = "<a href=' "+str+" ' > testlink </a>";
}    
</script>
<div>
    id = "t"
</div>
<input> type="text" id="text" value="" />
<input> type="button" id="s" value="write"   />

     正常構(gòu)造數(shù)據(jù),www.a.com。

     點(diǎn)擊write按鈕:頁(yè)面顯示www.a.com鏈接

 

     非正常構(gòu)造如下數(shù)據(jù)

' onclick=alert(/xss/) //

     點(diǎn)擊write按鈕,頁(yè)面顯示testlink,點(diǎn)擊testlink,彈出/xss/警告框

     這里首先一個(gè)單引號(hào)閉合掉href第一個(gè)單引號(hào),然后插入一個(gè)onclick事件,最后再用注釋符注釋掉第一個(gè)單引號(hào)。

     這段代碼也可以通過(guò)閉合掉<a>的方式***:

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

     此時(shí)頁(yè)面代碼變成了:

<a href=' '>  <img src=# onerror=alert(/xss/) /> <' '>testlink</a> 

2.2 XSS防御

2.2.1 HttpOnly

      設(shè)置cookie httponly標(biāo)記,可以禁止JavaScript訪問(wèn)帶有該屬性的cookie,目前主流的瀏覽器已經(jīng)支持HttpOnly

2.2.2 輸入檢查

2.2.3 輸出檢查

      安全的編碼函數(shù):在數(shù)據(jù)添加到DOM時(shí)候,我們可以需要對(duì)內(nèi)容進(jìn)行HtmlEncodeJavaScriptEncode,以預(yù)防XSS***。 JavaScriptEncode 使用“\”對(duì)特殊字符進(jìn)行轉(zhuǎn)義,除數(shù)字字母之外,小于127的字符編碼使用16進(jìn)制“\xHH”的方式進(jìn)行編碼,大于用unicode(非常嚴(yán)格模式)。除了HTMLEncode、JavaScriptEncode外還有XMLEncodeJSONEncode等編碼函數(shù),在php中有htmlentities()htmlspcialchars()兩個(gè)函數(shù)可以滿足要求。

      XSS***主要發(fā)生在MVC架構(gòu)的view層,大部分的XSS漏洞可以在模板系統(tǒng)中解決。

      python的開(kāi)發(fā)框架Django自帶的模板系統(tǒng)中,可以使用escape進(jìn)行htmlencode,比如:

{{ var | escape }}

      這樣寫(xiě)的變量,會(huì)被HtmlEncode

2.2.4 正確防御XSS

場(chǎng)景一:在HTML標(biāo)簽中輸出

<div>$var</div>
<a href=#>$var</a>

      所有在標(biāo)簽中輸出的變量,如果未做任何處理,都會(huì)導(dǎo)致直接產(chǎn)生XSS

      在這種場(chǎng)景下,XSS的利用方式一般構(gòu)造一個(gè)<script>標(biāo)簽,或者是任何能夠產(chǎn)生腳本的執(zhí)行方式。比如:

<div><script>alert(/xss/) </script></div>

     或者

<a href=#> <img src=#onerror=alert(1) /> </a>

防御的方式是對(duì)變量使用HtmlEncode

場(chǎng)景二:在HTML屬性中輸出

<div id="abc" name="$var"></div>

 與在HTML標(biāo)簽中輸出類(lèi)似,可能的***方式

<div id="abc" name=""><script>alert(/xss/)</script><"" ></div>

防御的方法也是HtmlEncode。

OWASP ESAPI中推薦課一個(gè)更嚴(yán)格的HTMLEncode--除了字幕、數(shù)字外,其他所有字符都被編碼成HTMLEntities。

String safe=ESAPI.encoder().encodeForHTMLAttribute(request.getParameter("input"));

場(chǎng)景三:在<script>標(biāo)簽中輸出 

<script>標(biāo)簽中輸出時(shí),首先應(yīng)該確保輸出的變量在引號(hào)中

<script>
 var x = "$var";
</script>

 ***者需要閉合引號(hào)才能實(shí)施***

<script>
 var x = "
";alert(/xss);//";     注://表示注釋后面的內(nèi)容
</script>

 防御時(shí)使用JavascriptEncode。

場(chǎng)景四:在事件中輸出

在事件中輸出和在<script>標(biāo)簽中輸出類(lèi)似:

<a href=# onclick="funcA('')">test</a>

可能***方法是:

<a href=# onclick="funcA('');alert(/xss/);\\')">test</a>

防御時(shí)使用JavascriptEncode。

場(chǎng)景四:在CSS中輸出

      盡可能禁止用戶可控制的變量在"<style>標(biāo)簽",如果一定有這樣的需求,則推薦使用OWASP ESAPI中的encodeForCSS()函數(shù)

場(chǎng)景五:在地址中輸出

      在地址中輸出比較復(fù)雜。一般來(lái)說(shuō),在URLpath或參數(shù)中輸出,使用URLEncode即可。URLEncode會(huì)將字符轉(zhuǎn)換為"%HH"形式,比如空格就是"%20","<"符號(hào)是"<%3c>"

<a >test</a>

可能的***方法是: 

<a href="http://www.evil.com/?test=" onclick=alert(1)""  >test</a>

經(jīng)過(guò)URLEncode后,變成了:

<a >test</a>

     還有一種情況,如果變量是整個(gè)URL (href="$var"),此時(shí)***者可能會(huì)構(gòu)造偽協(xié)議實(shí)施***:

<a href="javascript:alert(1);">test</a>

      一般來(lái)說(shuō),如果變量是整個(gè)URL,則應(yīng)該先檢查變量是否是以http開(kāi)頭(如果不是則自動(dòng)添加),以保證不會(huì)出現(xiàn)偽協(xié)議類(lèi)的XSS***。在此之后,再對(duì)變量進(jìn)行URLEncode,以保證不會(huì)出現(xiàn)偽協(xié)議類(lèi)的XSS***。

2.2.4 處理富文本

     允許用戶提交一些自定義的HTML代碼,稱(chēng)之為"富文本",如論壇帖子里發(fā)表的圖片、視頻、表格等。在處理富文本的時(shí)候還是要回到"輸出檢查"的思路上來(lái)。

2.2.5 防御DOM Based XSS

    DOM Based XSS 是一種比較特別的XSS漏洞,前文提到的幾種防御方法都不太適用,需要特別對(duì)待。

   以以下案例:

<script>

  var x="\x20\x27onclick\x3dalert\x281\x29\x3b\x2f\x2fx27";   //<a href='""'onclick=(alert(1));//'

  document.write("<a href='"+x+"'>test</a>");

</script>


     這段代碼最終輸出彈框1,被XSS***。原因在于,第一次執(zhí)行JavaScriptEscape后只保護(hù)了:  

   var x = "$var"

      但是當(dāng)document.write輸出數(shù)據(jù)到Html頁(yè)面時(shí),瀏覽器重新渲染了頁(yè)面。在<script>標(biāo)簽執(zhí)行時(shí),已經(jīng)對(duì)x進(jìn)行了解碼,氣候在document.write再運(yùn)行時(shí),其參數(shù)變成了:

  href='""'onclick=(alert(1));//'

     預(yù)防方式是:首先在$var輸出到<script>時(shí),應(yīng)該執(zhí)行一次JavaScriptEncode;其次在document.write輸出到html頁(yè)面時(shí)要分具體情況看待:如果輸出到事件或腳本,則要做一次JavaScriptEncode;如果輸出到Html內(nèi)容或者屬性,則要做一次HTMLEncode。



向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI