XSS漏洞
XSS(跨站指令碼攻擊,Cross-Site Scripting)是一種安全漏洞,通常發生在Web應用程式中。XSS漏洞允許攻擊者把惡意指令碼注入到內容中, 這會在其他使用者的瀏覽器中執行。這種攻擊可能導致使用者會話被劫持、網站內容被修改、使用者敏感資訊被竊取等多種安全問題。常見的XSS型別包括:
- 儲存型XSS:惡意指令碼被儲存在目標伺服器上,比如在資料庫中。比如當使用者在一個留言板上輸入程式碼,程式碼被儲存下來了,訪問該頁面的其他使用者就會受到影響。
- 反射型XSS:惡意指令碼透過URL等手段被“反射”到使用者的瀏覽器中,常在帶有查詢引數的連結中實施。使用者點選惡意連結時,會立即執行該指令碼。
- DOM型XSS:基於文件物件模型(DOM)的變化,在客戶端執行的XSS。DOM型XSS攻擊不會涉及到伺服器端內容改變。
防禦XSS攻擊的方法包括:
- 對使用者輸入進行嚴格的驗證和過濾。
- 對輸出進行編碼,確保瀏覽器不能將其錯誤地解釋為可執行程式碼。
- 使用安全的HTTP頭,如Content Security Policy(CSP)。
DOM型XSS
low
直接嘗試
原始碼審計
沒有任何過濾情況
<?php
//沒有保護,什麼都沒有
# No protections, anything goes
?>
medium
檢視原始碼發現過濾掉了“<script”,當函式匹配到 <script 字串的時候就會將URL後面的引數修正為 ?default=English
繞過
原始碼審計
過濾了<script 欄位,可以雙寫繞過,或者大小寫繞過
<?php
// 檢查是否有輸入
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
$default = $_GET['default']; // 獲取查詢引數 'default' 的值並賦給變數 $default
# 不允許含有 script 標籤
if (stripos ($default, "<script") !== false) {
header ("location: ?default=English"); // 如果檢測到 <script> 標籤,則重定向到 ?default=English
exit; // 終止指令碼執行
}
}
?>
high
這裡設定了白名單,如果default的值不為”French”、”English”、”German”、”Spanish”的話就重置URL為:?default=English ,這裡只是對 default 的變數進行了過濾
可以考慮後面加 # 或 &
原始碼審計
首先確保有輸入資料,設定了白名單允許的語言,可以利用白名單語言進行繞過
<?php
// 檢查是否有輸入
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
# 白名單允許的語言
switch ($_GET['default']) {
case "French": // 法語
case "English": // 英語
case "German": // 德語
case "Spanish": // 西班牙語
# 合法的語言
break;
default:
header ("location: ?default=English"); // 如果輸入的語言不在白名單內,則重定向到 ?default=English
exit; // 終止指令碼執行
}
}
?>
impossible
原始碼審計
將防護移到客戶端,更加安全
<?php
# 不需要做任何事情,保護措施在客戶端處理
?>
反射型XSS (Reflected)
反射型XSS,顧名思義在於“反射”這個一來一回的過程。反射型XSS的觸發有後端的參與,而之所以觸發XSS是因為後端解析使用者在前端輸入的帶有XSS性質的指令碼或者指令碼的data URI編碼,後端解析使用者輸入處理後返回給前端,由瀏覽器解析這段XSS指令碼,觸發XSS漏洞。因此如果要避免反射性XSS,則必須需要後端的協調,在後端解析前端的資料時首先做相關的字串檢測和轉義處理;同時前端同樣也許針對使用者的資料做excape轉義,保證資料來源的可靠性
-
基本原理就是透過給別人傳送帶有惡意指令碼程式碼引數的URL,當URL地址被開啟時,特定的程式碼引數會被HTML解析,執行,如此就可以獲取使用者的COOIKE,進而盜號登陸。
-
特點:非持久化 必須使用者點選帶有特定引數的連結才能引起。
-
XSS反射型攻擊,惡意程式碼並沒有儲存在目標網站,透過引誘使用者點選一個連結到目標網站的惡意連結來實施攻擊的。
low
並沒有任何過濾
原始碼審計
<?php
header ("X-XSS-Protection: 0"); // 設定 HTTP 頭部,關閉 XSS 攻擊防護
// 檢查是否有輸入
// array_key_exists() 函式:判斷 $_GET 的值中是否存在 “name” 鍵名,並且 $_GET[‘name’] 的值是否不為空,滿足這些條件,直接輸出下面的輸出語句。
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// 給終端使用者的反饋
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; // 輸出問候資訊,包含使用者輸入的名稱
}
?>
medium
這裡過濾了<script標籤,這裡使用了str_replace函式,它是區分大小寫的,因此可以使用大小寫繞過
也可以使用雙寫繞過
原始碼審計
過濾了