Xiuno BBS 审计之问题13:管理员发帖 doctype=0 时存储型 XSS

问题:管理员发帖 doctype=0 时存储型 XSS(绕过 htmlspecialchars)

此文章为XIUNOX版本重构审计时发现问题,XIUNOX版本已优化修复此问题。分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。

现象

Xiuno BBS 4.0.4 在帖子内容入库格式化时,对 doctype=0(HTML 类型)的处理存在特权分支:当发帖人 gid==1(管理员组)时,原文 message 未经 htmlspecialchars 也未经 xn_html_safe 白名单过滤,直接赋值给 message_fmt 入库。前台模板 post_list.inc.htm、thread.htm 又以 <?php echo $first['message_fmt'];?> 原样输出,未做二次转义。

攻击者只要拿到管理员账号(或通过弱口令、CSRF 劫持后台),即可在帖子中植入任意 <script>,对所有浏览该帖的访客(含其他管理员、版主、普通会员)执行存储型 XSS,进而窃取 bbs_token/bbs_admin_token、伪造操作、挂马、水坑攻击。

源码证据

证据 1:入库格式化逻辑------gid==1 且 doctype==0 时跳过转义 文件:xiunobbs_4.0.4/model/post.func.php 行 349-361

php 复制代码
// 写入时格式化
function post_message_fmt(&$arr, $gid) {
	// hook post_message_fmt_start.php
	// 超长内容截取
	$arr['message'] = xn_substr($arr['message'], 0, 2028000);
	// 格式转换: 类型,0: html, 1: txt; 2: markdown; 3: ubb
	$arr['message_fmt'] = htmlspecialchars($arr['message']);
	// 入库的时候进行转换,编辑的时候,自行调取 message, 或者 message_fmt
	$arr['doctype'] == 0 && $arr['message_fmt'] = ($gid == 1 ? $arr['message'] : xn_html_safe($arr['message']));
	$arr['doctype'] == 1 && $arr['message_fmt'] = xn_txt_to_html($arr['message']);
}

第 360 行:$arr['doctype'] == 0 && $arr['message_fmt'] = ($gid == 1 ? $arr['message'] : xn_html_safe($arr['message']));

  • gid==1(管理员)→ message_fmt = message(原始 HTML,无任何过滤)
  • gid!=1 → message_fmt = xn_html_safe(message)(白名单过滤)

证据 2:前台模板原样输出 message_fmt,无二次转义 文件:xiunobbs_4.0.4/view/htm/post_list.inc.htm 行 64

php 复制代码
<?php echo $_post['message_fmt'];?>

文件:xiunobbs_4.0.4/view/htm/thread.htm 行 61

php 复制代码
<?php echo $first['message_fmt'];?>

两处均为裸 echo,未调用 htmlspecialchars,直接将入库的 message_fmt 输出到 HTML 文档流。

风险等级与结论

风险等级:高危

结论:

  1. 管理员发 HTML 帖(doctype=0)时内容不经任何转义/过滤直入库,前台裸输出,构成存储型 XSS。
  2. 虽然利用前提是管理员权限,但管理员账号常成为攻击目标(弱口令 md5、CSRF 无 token、Cookie 无 Secure),一旦被攻陷即可借此 XSS 横向打击全站用户,形成"管理员失陷→全站水坑"的攻击链。
  3. xn_html_safe 白名单本应作为兜底,但对 gid==1 完全豁免,属于典型的"信任管理员"假设缺陷------管理员账号被盗后该假设即失效。
  4. 修复建议:取消 gid==1 豁免分支,所有 doctype=0 内容统一经 xn_html_safe 白名单过滤;或在模板输出端对 message_fmt 强制二次转义;同时引入 CSP 头降低 XSS 危害。
相关推荐
郭小李40 分钟前
spring 的 @CookieValue 注解 用法
java·后端·spring
god_cvz1 小时前
麒麟 V10(ARM64 / aarch64)源码编译 3dtiles 全步骤
后端·gis
武子康1 小时前
批量设备任务显示 COMPLETED,为什么还有设备失败?
人工智能·后端·agent
泡海椒1 小时前
折线图Y轴刻度悬空之谜-信用评级趋势
后端
.Bryce.1 小时前
T2-LLM评测不等于Agent评测
android·java·人工智能·后端·gpt·agent·1024程序员节
SH的全栈笔记2 小时前
敲下 git add 的那一刻,.git 里多了什么
git·后端
用户298698530142 小时前
Python 将 Word 文档转换为 XML 的实践要点
后端·python·api
Java爱好狂.3 小时前
阿里1658页Java面试题总结(含答案)
java·后端·高并发·架构师·java面试·java面试题·java八股文
vipxieliang3 小时前
PHP Swoole 协程模型详解:协程与线程/进程、调度、常驻内存及与 Go goroutine 的异同
后端·php
lazy H3 小时前
【计算机网络】第 12 篇:IPv6 详解——地址格式、地址类型与双栈网络
网络·经验分享·后端·学习·计算机网络·408