AI 学习经验
ChatGPT 账号是怎么被一个分享链接攻破的:一条完整的 XSS 攻击链
Parameter Labs 披露了针对 ChatGPT HTML 预览(原 Canvas)沙箱的一整套攻击链:从 MathLive 虚拟键盘的 postMessage 入口,到 innerHTML 注入、绕过 CSP,最终在 ChatGPT 页面里执行任意 JavaScript,窃取登录用户的私有数据。OpenAI 已修复并支付 5000 美元赏金。
今天就能做
- 检查自己项目里所有 postMessage 监听器,补上 event.origin 和消息结构校验。
- 把渲染用户生成 HTML 的代码过一遍,找出 innerHTML 拼接点并替换为安全写法。
- 审查 CSP 放行的第三方域名,确认其中没有能反射 JavaScript 的接口。
攻击面:沙箱 iframe 与父页面之间的消息通道
- ChatGPT 的 HTML 预览把用户写的交互式 HTML 应用放在沙箱 iframe 里运行,设计前提是这段不可信代码不能碰到 OpenAI 的 API 和用户私有数据。
- OpenAI 用 MathLive 这个 JavaScript 库支持图形渲染,它自带一个虚拟键盘,父页面可以通过 postMessage() 从沙箱 iframe 触发它。
- 问题出在接收消息的代码用了 innerHTML 写入内容,而且没有校验消息来源,任何沙箱 frame(包括 HTML 预览 frame)都能调用。
从注入 HTML 到执行脚本
- innerHTML 本身不会直接执行 script 标签,但攻击者可以借它注入一个不带 sandbox 限制的新 iframe,把执行环境换掉。
- OpenAI 的 CSP 禁止内联脚本,只放行少数几个域名加载脚本,其中包含 YouTube。
- YouTube 的 oEmbed 接口可以把 JavaScript 反射回来,正好绕开 CSP 的白名单限制,拿到真正的脚本执行权限。
拿到执行权限之后
- 一旦在 ChatGPT 页面上下文里跑起 JavaScript,调用 API 读取当前登录用户的私有数据就变得很简单。
- 外传数据也不需要复杂通道,用一个图片引用就能把数据带出去。
- 最终形态是一条 ChatGPT 分享链接:任何已登录用户点开,都可能被窃取数据或以他的身份执行操作。
修复与赏金
- OpenAI 已关闭该漏洞,并支付了 5000 美元 bug bounty。
- 作者 Simon Willison 认为,对这么严重的漏洞来说,这个金额偏低。
对做 AI 应用的人的启示
- 只要你的产品在 iframe 里渲染用户或模型生成的 HTML,就要把 postMessage 的 origin 校验和消息 schema 校验当成硬性要求。
- 避免用 innerHTML 拼接来自消息通道的内容,改用 textContent 或显式白名单构建 DOM。
- CSP 的域名白名单不是安全边界,像 oEmbed 这类能反射内容的第三方接口会把它变成跳板,需要逐个审查放行域名。
登录后可以点赞、查看和发表评论