跨站腳本漏洞(XSS)基礎(chǔ)講解

XSS漏洞

一、文章簡介

XSS漏洞是Web應(yīng)用程序中最常見的漏洞之一享怀。如果您的站點沒有預(yù)防XSS漏洞的固定方法逾苫,那么很可能就存在XSS漏洞。
這篇文章將帶你通過代碼層面去理解三個問題:

  • 什么是XSS漏洞部服?

  • XSS漏洞有哪些分類?

  • 如何防范XSS漏洞拗慨?

二饲宿、XSS 漏洞簡介

跨站腳本攻擊是指惡意攻擊者往Web頁面里插入惡意Script代碼厦酬,當(dāng)用戶瀏覽該頁之時胆描,嵌入其中Web里面的Script代碼會被執(zhí)行瘫想,從而達到惡意攻擊用戶的目的。
xss漏洞通常是通過php的輸出函數(shù)將javascript代碼輸出到html頁面中昌讲,通過用戶本地瀏覽器執(zhí)行的国夜,所以xss漏洞關(guān)鍵就是尋找參數(shù)未過濾的輸出函數(shù)
常見的輸出函數(shù)有: echo printf print print_r sprintf die var-dump var_export.

xss 分類:(三類)

  • 反射型XSS:<非持久化> 攻擊者事先制作好攻擊鏈接, 需要欺騙用戶自己去點擊鏈接才能觸發(fā)XSS代碼(服務(wù)器中沒有這樣的頁面和內(nèi)容)短绸,一般容易出現(xiàn)在搜索頁面车吹。

  • 存儲型XSS:<持久化> 代碼是存儲在服務(wù)器中的,如在個人信息或發(fā)表文章等地方醋闭,加入代碼窄驹,如果沒有過濾或過濾不嚴(yán),那么這些代碼將儲存到服務(wù)器中证逻,每當(dāng)有用戶訪問該頁面的時候都會觸發(fā)代碼執(zhí)行乐埠,這種XSS非常危險,容易造成蠕蟲囚企,大量盜竊cookie(雖然還有種DOM型XSS丈咐,但是也還是包括在存儲型XSS內(nèi))。

  • DOM型XSS:基于文檔對象模型Document Objeet Model龙宏,DOM)的一種漏洞棵逊。DOM是一個與平臺、編程語言無關(guān)的接口银酗,它允許程序或腳本動態(tài)地訪問和更新文檔內(nèi)容辆影、結(jié)構(gòu)和樣式,處理后的結(jié)果能夠成為顯示頁面的一部分黍特。DOM中有很多對象蛙讥,其中一些是用戶可以操縱的,如uRI 衅澈,location键菱,refelTer等〗癫迹客戶端的腳本程序可以通過DOM動態(tài)地檢查和修改頁面內(nèi)容经备,它不依賴于提交數(shù)據(jù)到服務(wù)器端,而從客戶端獲得DOM中的數(shù)據(jù)在本地執(zhí)行部默,如果DOM中的數(shù)據(jù)沒有經(jīng)過嚴(yán)格確認侵蒙,就會產(chǎn)生DOM XSS漏洞。

三傅蹂、XSS 漏洞原理

3.1 反射型XSS

在黑盒測試中纷闺,這種類型比較容易通過漏洞掃描器直接發(fā)現(xiàn)算凿,我們只需要按照掃描結(jié)果進行相應(yīng)的驗證就可以了。

相對的在白盒審計中犁功, 我們首先要尋找?guī)?shù)的輸出函數(shù)氓轰,接下來通過輸出內(nèi)容回溯到輸入?yún)?shù),觀察是否過濾即可浸卦。
無案例不足以求真署鸡,這里我們選用echo()函數(shù)作為實例來分析:

新建 XssReflex.php,代碼如下:

<html>
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>XSS</title> 
</head> 
<body> 
<form action="" method="get"> 
<input type="text" name="input">     
<input type="submit"> 
</form> 
<br> 
<?php 
$XssReflex = $_GET['input'];
echo 'output:<br>'.$XssReflex;
?> 
</body> 
</html> 

這是一個很簡單限嫌、也很常見的頁面:
變量 $XssReflex 獲取 get 方式傳遞的變量名為 input 的變量值(值為一個字符串)靴庆,然后直接通過echo()函數(shù)輸出,注意這中間并未對用戶輸入進行任何過濾怒医。

打開Firefox輸入url:localhost/codeaudit/xss/XssReflex.php :

當(dāng)我們輸入 1 炉抒,頁面返回 1 :

當(dāng)我們輸入hello時,頁面返回 hello :

以上都為正常的輸出稚叹,但如果我們輸出一些javascript代碼呢焰薄?

比如我們輸入<script>alert('xss')</script>

可以看到瀏覽器成功彈窗,說明我們輸出的JavaScript代碼成功被執(zhí)行了入录。
我們查看網(wǎng)頁html代碼:


第12行增加了:

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

這個彈窗并沒有什么實際的意義蛤奥,但通過它我們知道輸入javascript代碼是可以被執(zhí)行的,當(dāng)我們輸入一些其他函數(shù)僚稿,比如document.cookie就可以成功盜取用戶的cookie信息凡桥,或者讀取用戶瀏覽器信息等,為我們進一步深入攻擊做鋪墊蚀同。

3.2 存儲型XSS

和反射性XSS的即時響應(yīng)相比缅刽,存儲型XSS則需要先把利用代碼保存在比如數(shù)據(jù)庫或文件中,當(dāng)web程序讀取利用代碼時再輸出在頁面上執(zhí)行利用代碼蠢络。但存儲型XSS不用考慮繞過瀏覽器的過濾問題衰猛,屏蔽性也要好很多。
存儲型XSS攻擊流程:


存儲型XSS的白盒審計同樣要尋找未過濾的輸入點和未過濾的輸出函數(shù)刹孔。

使用cat命令查看 XssStorage.php 代碼

shiyanlou:~/ $ cat XssStorage.php

代碼如下:<參考自JackholeLiu的博客>

    <span style="font-size:18px;"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>  
    <html>  
    <head>  
    <title>XssStorage</title>  
    </head>  
    <body>  
    <h2>Message Board<h2>  
    <br>
    <form action="XssStorage.php" method="post">  
    Message:<textarea id='Mid' name="desc"></textarea>  
    <br>  
    <br>  
    Subuser:<input type="text" name="user"/><br> 
    <br>
    <input type="submit" value="submit" onclick='loction="XssStorage.php"'/>  
    </form>  
    <?php  
    if(isset($_POST['user'])&&isset($_POST['desc'])){  
    $log=fopen("sql.txt","a");  
    fwrite($log,$_POST['user']."\r\n");  
    fwrite($log,$_POST['desc']."\r\n");  
    fclose($log);  
    }  
      
    if(file_exists("sql.txt"))  
    {  
    $read= fopen("sql.txt",'r');  
    while(!feof($read))  
    {  
        echo fgets($read)."</br>";  
    }  
    fclose($read);  
    }  
    ?>  
    </body>  
    </html></span>  

頁面功能簡述:

這個頁面采用POST提交數(shù)據(jù)啡省,生成、讀取文本模擬數(shù)據(jù)庫髓霞,提交數(shù)據(jù)之后頁面會將數(shù)據(jù)寫入sql.txt卦睹,再打開頁面時會讀取sql.txt中內(nèi)容并顯示在網(wǎng)頁上,實現(xiàn)了存儲型xss攻擊模擬方库。

打開Firefox輸入url:localhost/codeaudit/xss/XssStorage.php :

我們隨意輸出一些內(nèi)容:


可以看到頁面正常顯示頁面留言信息结序。
當(dāng)我們在Message中輸入<script>alert('xss')</script>時,頁面成功彈窗 :

并且我們重啟瀏覽器之后再加載該頁面纵潦,頁面依然會彈窗,這是因為惡意代碼已經(jīng)寫入數(shù)據(jù)庫中徐鹤,每當(dāng)有人訪問該頁面時垃环,惡意代碼就會被加載執(zhí)行!

我們查看網(wǎng)頁html代碼:


這就是所謂的存儲型XSS漏洞返敬,一次提交之后遂庄,每當(dāng)有用戶訪問這個頁面都會受到XSS攻擊,危害巨大救赐。

3.3 DOM XSS

這種XSS用的相對較少涧团,并且由于其特殊性,常見的漏掃工具都無法檢測出來经磅,這里先不做講解。

記個待辦钮追,以后來補预厌!

四、XSS漏洞防范

4.1 反射型xss漏洞防范

php中xss的漏洞防范方法總結(jié):<參考自Segmentfault>

A.PHP直接輸出html的元媚,可以采用以下的方法進行過濾:

    1.htmlspecialchars函數(shù)
    2.htmlentities函數(shù)
    3.HTMLPurifier.auto.php插件
    4.RemoveXss函數(shù)

B.PHP輸出到JS代碼中轧叽,或者開發(fā)Json API的,則需要前端在JS中進行過濾:

    1.盡量使用innerText(IE)和textContent(Firefox),也就是jQuery的text()來輸出文本內(nèi)容
    2.必須要用innerHTML等等函數(shù)刊棕,則需要做類似php的htmlspecialchars的過濾

C.其它的通用的補充性防御手段

    1.在輸出html時炭晒,加上Content Security Policy的Http Header
    (作用:可以防止頁面被XSS攻擊時,嵌入第三方的腳本文件等)
    (缺陷:IE或低版本的瀏覽器可能不支持)
    2.在設(shè)置Cookie時甥角,加上HttpOnly參數(shù)
    (作用:可以防止頁面被XSS攻擊時网严,Cookie信息被盜取,可兼容至IE6)
    (缺陷:網(wǎng)站本身的JS代碼也無法操作Cookie嗤无,而且作用有限震束,只能保證Cookie的安全)
    3.在開發(fā)API時,檢驗請求的Referer參數(shù)
    (作用:可以在一定程度上防止CSRF攻擊)
    (缺陷:IE或低版本的瀏覽器中当犯,Referer參數(shù)可以被偽造)


這里我們選用htmlentities()函數(shù)進行測試:

htmlentities() 函數(shù)把字符轉(zhuǎn)換為 HTML 實體垢村。

新建Xss_htmlentities.php, 代碼如下:

<html>
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>XSS</title> 
</head> 
<body> 
<form action="" method="get"> 
<input type="text" name="input">     
<input type="submit"> 
</form> 
<br> 
<?php 
$XssReflex = $_GET['input'];
echo 'output:<br>'.htmlentities($XssReflex);#僅在這里對變量 $XssReflex 做了處理.
?> 
</body> 
</html> 

在Firefox輸入url:localhost/codoaudit/xss/Xsshtmlentities.php :

當(dāng)我們輸入<script>alert('xss')</script>

可以看到頁面并沒有彈窗嚎卫。
我們再查看網(wǎng)頁html代碼:


可以看到htmlentities()函數(shù)對用戶輸入的<>做了轉(zhuǎn)義處理,惡意代碼當(dāng)然也就沒法執(zhí)行了嘉栓。
還有其他過濾函數(shù),紙上學(xué)來終覺淺拓诸,有興趣的同學(xué)可以自己去嘗試一番

4.2 存儲型xss漏洞防范

存儲型XSS對用戶的輸入進行過濾的方式和反射型XSS相同侵佃,這里我們使用htmlspecialchars()函數(shù)進行演示:

htmlentities() :把預(yù)定義的字符 "<" (小于)和 ">" (大于)轉(zhuǎn)換為 HTML 實體

htmlspecialchars和htmlentities的區(qū)別:

htmlspecialchars 只轉(zhuǎn)義 & 、" 恰响、' 趣钱、< 、> 這幾個html代碼胚宦,而 htmlentities 卻會轉(zhuǎn)化所有的html代碼首有,連同里面的它無法識別的中文字符也會轉(zhuǎn)化燕垃。

新建Xss_htmlspecialchars_Storage.php ,代碼如下:

    <span style="font-size:18px;"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>  
    <html>  
    <head>  
    <title>XssStorage</title>  
    </head>  
    <body>  
    <h2>Message Board<h2>  
    <br>
    <form action="Xss_htmlspecialchars_Storage.php" method="post">  
    Message:<textarea id='Mid' name="desc"></textarea>  
    <br>  
    <br>  
    Subuser:<input type="text" name="user"/><br> 
    <br>
    <input type="submit" value="submit" onclick='loction="XssStorage.php"'/>  
    </form>  
    <?php  
    if(isset($_POST['user'])&&isset($_POST['desc'])){  
    $log=fopen("sqlStorage.txt","a");  
    fwrite($log,htmlspecialchars($_POST['user'])."\r\n"); # 在此對用戶輸入數(shù)據(jù)$_POST['user']進行過濾
    fwrite($log,htmlspecialchars($_POST['desc'])."\r\n"); # 在此對用戶輸入數(shù)據(jù)$_POST['desc']進行過濾
    fclose($log);  
    }  
      
    if(file_exists("sqlStorage.txt"))  
    {  
    $read= fopen("sqlStorage.txt",'r');  
    while(!feof($read))  
    {  
        echo fgets($read)."</br>";  
    }  
    fclose($read);  
    }  
    ?>  
    </body>  
    </html></span>  

在Firefox輸入url:localhost/codoaudit/xss/Xss_htmlspecialchars_Storage.php :

當(dāng)我們在Message中輸入<script>alert('xss')</script>

可以看到頁面并沒有彈窗井联。
我們再查看網(wǎng)頁html代碼:


可以看到htmlspecialchars()函數(shù)對用戶輸入的<>做了轉(zhuǎn)義處理卜壕。

五、總結(jié)及回顧

  • XSS漏洞原理和相關(guān)函數(shù):eval() assert() preg_replace() 回調(diào)函數(shù) 動態(tài)執(zhí)行函數(shù)
  • XSS漏洞的防范

如果你覺得這篇文章講的不錯的話烙常,可以關(guān)注我的其他文章和課程:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚕脏,一起剝皮案震驚了整個濱河市侦副,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驼鞭,老刑警劉巖秦驯,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挣棕,居然都是意外死亡译隘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門洛心,熙熙樓的掌柜王于貴愁眉苦臉地迎上來固耘,“玉大人,你說我怎么就攤上這事词身√浚” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵偿枕,是天一觀的道長璧瞬。 經(jīng)常有香客問我,道長渐夸,這世上最難降的妖魔是什么嗤锉? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮墓塌,結(jié)果婚禮上瘟忱,老公的妹妹穿的比我還像新娘。我一直安慰自己苫幢,他們只是感情好访诱,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著韩肝,像睡著了一般触菜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哀峻,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天涡相,我揣著相機與錄音哲泊,去河邊找鬼。 笑死催蝗,一個胖子當(dāng)著我的面吹牛切威,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播丙号,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼先朦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了犬缨?” 一聲冷哼從身側(cè)響起喳魏,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遍尺,沒想到半個月后截酷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡乾戏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了三热。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鼓择。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖就漾,靈堂內(nèi)的尸體忽然破棺而出呐能,到底是詐尸還是另有隱情,我是刑警寧澤抑堡,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布摆出,位于F島的核電站,受9級特大地震影響首妖,放射性物質(zhì)發(fā)生泄漏偎漫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一有缆、第九天 我趴在偏房一處隱蔽的房頂上張望象踊。 院中可真熱鬧,春花似錦棚壁、人聲如沸杯矩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽史隆。三九已至,卻和暖如春曼验,著一層夾襖步出監(jiān)牢的瞬間泌射,已是汗流浹背粘姜。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留魄幕,地道東北人相艇。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像纯陨,于是被迫代替她去往敵國和親坛芽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354