您好,登錄后才能下訂單哦!
一、瀏覽器安全
1、同源策略(SOP)
在瀏覽器中,<script>、<img>、<iframe>、<link>等標簽都可以跨域加載資源,而不受同源限制。這些帶src屬性的標簽每次加載時,實際上是有瀏覽器發起了一次GET請求。不同于XMLHttpRequest(通過目標域返回的HTTP頭"Access-Control-Allow-Origin:* *允許訪問自己的域"來授權是否允許跨域訪問,因為HTTP頭對JavaScript來說一般是無法控制的)的是,通過src屬性加載的資源,瀏覽器限制了JavaScript的權限,使其不能讀、寫返回的內容。
2、瀏覽器沙箱(Sandbox)
3、惡意網站攔截
二、跨腳本***(XSS)
2.1 XSS***類型
2.1.1、反射型XSS
通過用戶輸入的數據反射給瀏覽器,反射型XSS也叫“非持久型XSS”(Non-persistent XSS)
假設一個頁面把用戶輸入的參數直接輸出的頁面上:
<?php $input = $_GET["param"]; |
正常情況下,用戶想param提交的數據會展示在頁面里,如:
http://www.a.com/test.php?param=這是一個測試; |
此時查看源碼:
<div> 這是一個測試 </div> |
但如果提交一段HTML代碼:
http://www.a.com/test.php?param=<script>alert(/xss)</script>; |
再查看源碼:
<div> <script>alert(/xss)</script>; </div> |
2.1.2、存儲型XSS
***會把用戶的數據存儲在服務器端。
比較常見的場景是:***寫了一篇包含有惡意JavaScript代碼的博客文章,只要用戶訪問改文章,就會在他們的瀏覽器中執行這段惡意代碼,***會把惡意代碼保存到服務器端。所以這種方式也叫持久型XSS(Persistent XSS)。
2.1.3、DOM Based XSS
通過修改頁面的DOM節點形成XSS,稱之為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" /> |
正常構造數據,www.a.com。
點擊write按鈕:頁面顯示www.a.com鏈接
非正常構造如下數據:
' onclick=alert(/xss/) // |
點擊write按鈕,頁面顯示testlink,點擊testlink,彈出/xss/警告框
這里首先一個單引號閉合掉href第一個單引號,然后插入一個onclick事件,最后再用注釋符注釋掉第一個單引號。
這段代碼也可以通過閉合掉<a>的方式***:
'><img src=# onerror=alert(/xss/) /><' |
此時頁面代碼變成了:
<a href=' '> <img src=# onerror=alert(/xss/) /> <' '>testlink</a> |
2.2 XSS防御
2.2.1 HttpOnly
設置cookie httponly標記,可以禁止JavaScript訪問帶有該屬性的cookie,目前主流的瀏覽器已經支持HttpOnly
2.2.2 輸入檢查
2.2.3 輸出檢查
安全的編碼函數:在數據添加到DOM時候,我們可以需要對內容進行HtmlEncode或JavaScriptEncode,以預防XSS***。 JavaScriptEncode 使用“\”對特殊字符進行轉義,除數字字母之外,小于127的字符編碼使用16進制“\xHH”的方式進行編碼,大于用unicode(非常嚴格模式)。除了HTMLEncode、JavaScriptEncode外還有XMLEncode、JSONEncode等編碼函數,在php中有htmlentities()和htmlspcialchars()兩個函數可以滿足要求。
XSS***主要發生在MVC架構的view層,大部分的XSS漏洞可以在模板系統中解決。
在python的開發框架Django自帶的模板系統中,可以使用escape進行htmlencode,比如:
{{ var | escape }} |
這樣寫的變量,會被HtmlEncode
2.2.4 正確防御XSS
場景一:在HTML標簽中輸出
<div>$var</div> <a href=#>$var</a> |
所有在標簽中輸出的變量,如果未做任何處理,都會導致直接產生XSS
在這種場景下,XSS的利用方式一般構造一個<script>標簽,或者是任何能夠產生腳本的執行方式。比如:
<div><script>alert(/xss/) </script></div> |
或者
<a href=#> <img src=#onerror=alert(1) /> </a> |
防御的方式是對變量使用HtmlEncode
場景二:在HTML屬性中輸出
<div id="abc" name="$var"></div> |
與在HTML標簽中輸出類似,可能的***方式
<div id="abc" name=""><script>alert(/xss/)</script><"" ></div> |
防御的方法也是HtmlEncode。
在OWASP ESAPI中推薦課一個更嚴格的HTMLEncode--除了字幕、數字外,其他所有字符都被編碼成HTMLEntities。
String safe=ESAPI.encoder().encodeForHTMLAttribute(request.getParameter("input"));
場景三:在<script>標簽中輸出
在<script>標簽中輸出時,首先應該確保輸出的變量在引號中
<script> var x = "$var"; </script> |
***者需要閉合引號才能實施***
<script> var x = "";alert(/xss);//"; 注://表示注釋后面的內容 </script> |
防御時使用JavascriptEncode。
場景四:在事件中輸出
在事件中輸出和在<script>標簽中輸出類似:
<a href=# onclick="funcA('')">test</a> |
可能***方法是:
<a href=# onclick="funcA('');alert(/xss/);\\')">test</a> |
防御時使用JavascriptEncode。
場景四:在CSS中輸出
盡可能禁止用戶可控制的變量在"<style>標簽",如果一定有這樣的需求,則推薦使用OWASP ESAPI中的encodeForCSS()函數
場景五:在地址中輸出
在地址中輸出比較復雜。一般來說,在URL的path或參數中輸出,使用URLEncode即可。URLEncode會將字符轉換為"%HH"形式,比如空格就是"%20","<"符號是"<%3c>"。
<a >test</a> |
可能的***方法是:
<a href="http://www.evil.com/?test=" onclick=alert(1)"" >test</a> |
經過URLEncode后,變成了:
<a >test</a> |
還有一種情況,如果變量是整個URL (href="$var"),此時***者可能會構造偽協議實施***:
<a href="javascript:alert(1);">test</a> |
一般來說,如果變量是整個URL,則應該先檢查變量是否是以http開頭(如果不是則自動添加),以保證不會出現偽協議類的XSS***。在此之后,再對變量進行URLEncode,以保證不會出現偽協議類的XSS***。
2.2.4 處理富文本
允許用戶提交一些自定義的HTML代碼,稱之為"富文本",如論壇帖子里發表的圖片、視頻、表格等。在處理富文本的時候還是要回到"輸出檢查"的思路上來。
2.2.5 防御DOM Based XSS
DOM Based XSS 是一種比較特別的XSS漏洞,前文提到的幾種防御方法都不太適用,需要特別對待。
以以下案例:
<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***。原因在于,第一次執行JavaScriptEscape后只保護了:
var x = "$var" |
但是當document.write輸出數據到Html頁面時,瀏覽器重新渲染了頁面。在<script>標簽執行時,已經對x進行了解碼,氣候在document.write再運行時,其參數變成了:
href='""'onclick=(alert(1));//' |
預防方式是:首先在$var輸出到<script>時,應該執行一次JavaScriptEncode;其次在document.write輸出到html頁面時要分具體情況看待:如果輸出到事件或腳本,則要做一次JavaScriptEncode;如果輸出到Html內容或者屬性,則要做一次HTMLEncode。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。