xss 跨站脚本漏洞 php,跨站脚本漏洞(XSS)基础讲解
XSS漏洞
一、文章簡介
XSS漏洞是Web應(yīng)用程序中最常見的漏洞之一。如果您的站點沒有預(yù)防XSS漏洞的固定方法,那么很可能就存在XSS漏洞。
這篇文章將帶你通過代碼層面去理解三個問題:
什么是XSS漏洞?
XSS漏洞有哪些分類?
如何防范XSS漏洞?
二、XSS 漏洞簡介
跨站腳本攻擊是指惡意攻擊者往Web頁面里插入惡意Script代碼,當用戶瀏覽該頁之時,嵌入其中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ā)表文章等地方,加入代碼,如果沒有過濾或過濾不嚴,那么這些代碼將儲存到服務(wù)器中,每當有用戶訪問該頁面的時候都會觸發(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)過嚴格確認,就會產(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,代碼如下:
XSS$XssReflex = $_GET['input'];
echo 'output:
'.$XssReflex;
?>
這是一個很簡單、也很常見的頁面:
變量 $XssReflex 獲取 get 方式傳遞的變量名為 input 的變量值(值為一個字符串),然后直接通過echo()函數(shù)輸出,注意這中間并未對用戶輸入進行任何過濾。
打開Firefox輸入url:localhost/codeaudit/xss/XssReflex.php :
當我們輸入 1 ,頁面返回 1 :
當我們輸入hello時,頁面返回 hello :
以上都為正常的輸出,但如果我們輸出一些javascript代碼呢?
比如我們輸入 :
可以看到瀏覽器成功彈窗,說明我們輸出的JavaScript代碼成功被執(zhí)行了。
我們查看網(wǎng)頁html代碼:
第12行增加了:
這個彈窗并沒有什么實際的意義,但通過它我們知道輸入javascript代碼是可以被執(zhí)行的,當我們輸入一些其他函數(shù),比如document.cookie就可以成功盜取用戶的cookie信息,或者讀取用戶瀏覽器信息等,為我們進一步深入攻擊做鋪墊。
3.2 存儲型XSS
和反射性XSS的即時響應(yīng)相比,存儲型XSS則需要先把利用代碼保存在比如數(shù)據(jù)庫或文件中,當web程序讀取利用代碼時再輸出在頁面上執(zhí)行利用代碼。但存儲型XSS不用考慮繞過瀏覽器的過濾問題,屏蔽性也要好很多。
存儲型XSS攻擊流程:
存儲型XSS的白盒審計同樣要尋找未過濾的輸入點和未過濾的輸出函數(shù)。
使用cat命令查看 XssStorage.php 代碼
shiyanlou:~/ $ cat XssStorage.php
代碼如下:
XssStorageMessage Board
Message:
Subuser:
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)."";
}
fclose($read);
}
?>
頁面功能簡述:
這個頁面采用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)容:
可以看到頁面正常顯示頁面留言信息。
當我們在Message中輸入時,頁面成功彈窗 :
并且我們重啟瀏覽器之后再加載該頁面,頁面依然會彈窗,這是因為惡意代碼已經(jīng)寫入數(shù)據(jù)庫中,每當有人訪問該頁面時,惡意代碼就會被加載執(zhí)行!
我們查看網(wǎng)頁html代碼:
這就是所謂的存儲型XSS漏洞,一次提交之后,每當有用戶訪問這個頁面都會受到XSS攻擊,危害巨大。
3.3 DOM XSS
這種XSS用的相對較少,并且由于其特殊性,常見的漏掃工具都無法檢測出來,這里先不做講解。
記個待辦,以后來補!
四、XSS漏洞防范
4.1 反射型xss漏洞防范
php中xss的漏洞防范方法總結(jié):
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, 代碼如下:
XSS$XssReflex = $_GET['input'];
echo 'output:
'.htmlentities($XssReflex);#僅在這里對變量 $XssReflex 做了處理.
?>
在Firefox輸入url:localhost/codoaudit/xss/Xsshtmlentities.php :
當我們輸入 :
可以看到頁面并沒有彈窗。
我們再查看網(wǎng)頁html代碼:
可以看到htmlentities()函數(shù)對用戶輸入的<>做了轉(zhuǎn)義處理,惡意代碼當然也就沒法執(zhí)行了。
還有其他過濾函數(shù),紙上學來終覺淺,有興趣的同學可以自己去嘗試一番
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 ,代碼如下:
XssStorageMessage Board
Message:
Subuser:
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)."";
}
fclose($read);
}
?>
在Firefox輸入url:localhost/codoaudit/xss/Xss_htmlspecialchars_Storage.php :
當我們在Message中輸入 :
可以看到頁面并沒有彈窗。
我們再查看網(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)注我的其他文章和課程:
總結(jié)
以上是生活随笔為你收集整理的xss 跨站脚本漏洞 php,跨站脚本漏洞(XSS)基础讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php三位不够前面加0,php 格式化数
- 下一篇: php+中午截取,PHP_php字符串截