首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Discuz! XSS 跨站腳本漏洞全景分析:發帖、回帖、私訊、投票多入口攻擊與防禦

     編輯:PHP 相關知識

聲明

本文僅供安全研究、程式碼審計、防禦加固參考。嚴禁用於攻擊實際站點。所有漏洞已在 Discuz! 後續版本修復,請務必升級至最新版。

漏洞根因:輸出端缺乏編碼/過濾

Discuz! 早期版本 (2.x, 3.x) 多處直接輸出用戶可控資料 (標題、用戶名、投票選項) 至 HTML/JS 語境,未經 htmlspecialchars() 或白名單過濾,導致 反射型/儲存型 XSS。

主要攻擊入口分析

1. 發帖/回帖標題

# URL 範例
/post.php?action=newthread&fid=2&subject=

# 程式碼流程 (簡化)
$subject = $_GET['subject']; // 或 $_POST['subject']
// 缺乏過濾直接入庫
// 顯示時:
echo "

$subject

"; // 直接輸出,腳本執行

利用:惡意標題儲存後,所有瀏覽版面、主題列表、RSS 的用戶皆中招 (儲存型 XSS)。

2. 私訊 (PM) 收件人用戶名

# URL 範例
/pm.php?action=send&username=victim">";
// 導致屬性逃逸,執行腳本

進階利用鏈:

  1. 攻擊者構造惡意 PM 連結。
  2. 利用「推薦給好友」功能 (email 參數同樣未過濾) 偽裝官方發送。
  3. 誘騙受害者點擊,竊取 Cookie → 偽造登入狀態 → 掌管帳號。
  4. 配合 HttpOnly 繞過 (早期瀏覽器不支援)、MD5 碰撞/暴力破解密碼。

3. 投票參數注入

# 正常投票
/misc.php?action=votepoll&fid=2&tid=16980&pollanswers[]=0

# 異常參數
/misc.php?action=votepoll&fid=2&tid=16980&pollanswers[]=999
# n > 最大選項數,仍提交成功,新增空標題選項
# 可能導致邏輯錯誤、統計異常、陣列越界 (舊版 PHP)

4. 其他潛在入口

  • 簽名檔、個人資料欄位 (未嚴格過濾 HTML)。
  • RSS/Atom 匯出 (標題、內容未轉義)。
  • 後台管理員操作日誌 (管理員帳號被竊風險最高)。

實戰攻擊鏈重現 (教育用途)

# 1. 攻擊者在論壇發帖,標題包含:


# 2. 管理員/用戶瀏覽版面 → 腳本執行 → Cookie 發送至 evil.com

# 3. 攻擊者拿到 Cookie,在瀏覽器設定 Cookie:discuz_auth=xxx; discuz_uid=1

# 4. 直接訪問論壇,以管理員身分操作 (若無 HttpOnly、IP 綁定、UA 檢查)

# 5. 進一步:上傳 Webshell、修改模板、植入持久後門

修復與防禦策略

核心原則:輸出端編碼 + 輸入端驗證 + CSP

1. 統一輸出函數 (Discuz! 實際採用)

<?php
// source/function/function_core.php
function dhtmlspecialchars($string) {
    if (is_array($string)) {
        foreach ($string as $key => $val) {
            $string[$key] = dhtmlspecialchars($val);
        }
    } else {
        $string = str_replace(['&', '"', "'", '<', '>'], 
                              ['&', '"', ''', '<', '>'], $string);
        // 或 PHP 5.4+ 直接用 htmlspecialchars($string, ENT_QUOTES, 'UTF-8')
    }
    return $string;
}

// 模板/顯示層統一呼叫
echo "

" . dhtmlspecialchars($thread['subject']) . "

"; echo "";

2. 模板引擎自動轉義 (現代框架標配)

  • Smarty: {$var|escape:'htmlall'} 或設定 $smarty->escape_html = true。
  • Blade/Latte/Twig: 預設 {{ $var }} 自動轉義,需原始輸出用 {!! $var !!} / {% autoescape false %}。
  • Discuz! 內建模板標籤 {$var} 應在編譯期自動注入 dhtmlspecialchars。

3. 富文本內容:HTMLPurifier 白名單過濾

<?php
// 發帖/回帖儲存前 (或輸出前)
require_once 'HTMLPurifier.auto.php';
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.Allowed', 'p,b,strong,i,em,u,a[href|title],img[src|alt],br,ul,ol,li,blockquote');
$purifier = new HTMLPurifier($config);
$clean_content = $purifier->purify($raw_content);

4. HTTP 標頭防禦

// 入口檔案 (index.php, admin.php) 最早處
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self'; frame-ancestors 'self'; form-action 'self'; base-uri 'self';");
header("X-Content-Type-Options: nosniff");
header("X-Frame-Options: SAMEORIGIN");
header("Referrer-Policy: strict-origin-when-cross-origin");
// Cookie 設定
// setcookie('discuz_auth', $value, ['httponly' => true, 'secure' => true, 'samesite' => 'Lax']);

5. 投票/表單參數嚴格驗證

<?php
// misc.php votepoll
$pollanswers = $_GET['pollanswers'] ?? [];
$max_option = $poll['options']; // 從資料庫讀取選項數

foreach ($pollanswers as $aid) {
    $aid = intval($aid);
    if ($aid < 0 || $aid >= $max_option) {
        // 記錄異常、拒絕處理、回傳錯誤
        showmessage('vote_invalid_option');
    }
    // 正常計票邏輯
}

安全開發檢查清單

項目 檢查點 工具/方法
所有輸出是否經過 htmlspecialchars/模板自動轉義grep -r "echo \$" --include="*.php" | grep -v dhtmlspecialchars
HTML 屬性單引號包裹 + 轉義單引號統一雙引號屬性 + ENT_QUOTES
JavaScript 內嵌json_encode() 輸出變數var x = ;
URL 參數urlencode()<a href="?q=">
富文本HTMLPurifier 白名單單元測試驗證 XSS Payload 全部失效
CookieHttpOnly, Secure, SameSite瀏覽器開發者工具 Application 面板檢查
CSP部署報告模式 → 正式模式Report-URI / Sentry 收集違規報告

總結

Discuz! 早期 XSS 漏洞本質是「輸出端未編碼」。修復核心:統一輸出函數、模板自動轉義、富文本白名單、CSP、Cookie 安全屬性。現代框架 (Laravel, Symfony, ThinkPHP 6+) 預設解決 90% XSS,遺留專案請優先引入統一輸出函數並全站替換,再配合 CSP 部署。安全無絕對,持續審計、升級、監控才是正道。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved