-
-
[原创]当“头像”变成后门:Ghost CMS 存储型 XSS(CVE-2024-23724)
-
发表于: 2天前 645
-
时间:2023 年 12 月 —2024 年 2 月(MITRE 记录 CVE-2024-23724 公开日 2024-02-11)
主角/发现方:Rhino Security Labs(RhinoSec)研究团队(公开材料中最常被关联到 Tyler Ramsbey 等人的研究/传播)
受害者画像:使用 Ghost CMS(Node.js 开源专业出版 CMS)的团队与自托管站点——Ghost 的 Docker 镜像下载量以“亿级”计,公开案例里提到其用户群中不乏 Apple、Mozilla、OpenAI 这类品牌站点(是否“在用某个版本”取决于具体部署)。
不是入侵,更像是“合法功能的副作用”
Ghost 为内容团队协作设计了多级角色:最低是 Contributor(投稿者)——只能写草稿、不能发布,但能登录后台、能上传自定义头像。问题就卡在这个“头像”能力上:Ghost 允许头像使用 SVG,而 SVG 本质是 XML,可能携带 JavaScript(<script>、onload=等向量),当时在头像上传链路里并未做有效净化,于是“图片上传”变成了“脚本投递”。
RhinoSec 给出的攻击画面并不复杂,却足够刺眼:
- Contributor 上传一个恶意 SVG 当作头像(文件里内嵌 JS)。
- Ghost 给该头像生成一个可访问的直链/资源地址。
- 当更高权限的人——Editor / Administrator / 更关键的 Owner——在浏览器里“看到/打开”该资源(例如进入成员信息或直链被加载到可触发脚本的上下文),SVG 内的 JS 就在管理会话里执行。
- 既然脚本以当前管理员的身份运行,它就能继续调用后台 API:把攻击者账号升到 Administrator,再把 Owner 转让过去——而 Ghost 里 Owner 不能被其他管理员删除,还能动账单等最高敏感设置。
NVD/MITRE 对该漏洞的 CVSS 3.1 给到 9.0 CRITICAL(AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H),定性上也明确指向:存储型 XSS + 权限提升,通过含 JS 的 SVG 头像实现。
最值得警惕的不是“弹窗”,是厂商第一反应
整件事最让安全圈皱眉的,不是漏洞本身(SVG 带脚本这事属于老常识),而是披露过程中的态度细节。RhinoSec 公开披露的时间线要点是:
- 2023-12-08:向 Ghost 报告该问题。
- 2023-12-11:Ghost 回复的核心意思是——Staff 用户应当是被信任的,因此不打算把它当有效攻击面处理。
- 研究者继续补充“可形成实例接管”的完整链条后,最终 2024-02-13 左右把研究公开,并自己提交补丁思路:在上传/处理环节用 DOMPurify 对 SVG 做净化;Ghost 后续也围绕相关修复做了跟进(公开可见的关联 PR 如 #20264)。
换句话说:攻击起点只是“投稿者权限 + 头像上传”,但真正放大的,是把“内部账号天然可信”当成安全模型的默认假设。
不管你是不是用 Ghost,这类坑的通用止血法就三条,按优先级来:
- 头像/附件上传先断掉“可脚本格式”
头像只允许 jpg/png/webp;真要用 SVG,也必须在上传时做白名单式净化(剥离 <script>、on*事件、危险命名空间与外链),并在响应上加 X-Content-Type-Options: nosniff,尽量避免它在“后台同域”被当成可执行资源打开。
- 把“就算有脚本也难搞事”的底线拉满
- 认证凭据 cookie:HttpOnly + Secure + SameSite=Lax(至少)。
- 后台加 CSP:script-src 'self'(别给 unsafe-inline),并把 object-src 'none'封死,降低“意外执行”的转化率。
- 别再说“员工/作者/投稿者=可信边界”
审稿流/成员列表/头像预览本身就是攻击面:凡是用户输入最终会变成 HTML/会被浏览器作为活跃内容打开,就要按“不可信”处理,而不是靠角色名称来安慰自己。
赞赏
- [原创]当“头像”变成后门:Ghost CMS 存储型 XSS(CVE-2024-23724) 646
- [转帖]外文翻译 1213
- [转帖]CTF对抗帖子 1201
- 安全工具 1404