一条看起来完全正常的 ChatGPT 公共分享链接,可能在打开者已登录的会话里跑起攻击者的代码。安全公司 Parameter 在 10 月 18 日通过 OpenAI 漏洞赏金计划提交了这个问题,OpenAI 在 8 天后完成修复,并把严重等级从 P2 上调到 P1——其最高一档。Parameter 于 10 月 28 日公开了技术写作,OpenAI 为此支付 5000 美元赏金。
事件概述
攻击载体就是 ChatGPT 的「分享对话」功能。研究者构造了一个普通对话,通过公开链接分发出去——它可以出现在邮件、聊天消息、客服工单或社交帖子里,和任何一条真实的分享链接没有区别。受害者不需要安装任何东西,不需要加入工作区,也不需要经过攻击者的登录流程。
在最稳定的版本里,受害者打开链接后点击一次 ChatGPT 的 Preview(预览)按钮即触发;后续改进版把页面设置为自动打开 Preview,于是「打开链接」就成了唯一动作。
技术细节:沙箱没破,旁路破了
ChatGPT 能把对话里的一段 HTML 渲染成一个小网页,这就是 Preview 功能。由于这个页面可以容纳任意代码,ChatGPT 把它放在独立域名下的受限 frame 里运行,正常情况下读不到外面的主页面。这层沙箱本身没有被攻破。
突破口来自同一个对话里的第二个功能。分享内容中还包含一张交互式图表,绘制它会把一个名为 MathLive 的数学排版库加载进 ChatGPT 主页面。MathLive 加载后会在主页面上留下一个监听器,用来接收关于它屏幕键盘的消息。
跨 frame 传递消息只有在接收方校验来源时才是安全的。Parameter 发现这个监听器接受任意来源发来的键盘消息,而且消息允许携带原始 HTML。于是 Preview 可以越过边界,把攻击者的 HTML 交给可信的主页面。这段 HTML 又创建了一个浏览器视为 chatgpt.com 同源的新 frame,最后由 YouTube 加载的脚本提供在其中运行的代码——ChatGPT 的内容安全策略禁止内联脚本,却允许来自 YouTube 的脚本,这一步恰好绕过了它。
拿到登录态之后能做什么
代码运行在受害者的已登录会话中,权限与真实的 ChatGPT 站点相同。在受控测试里,它列出了受害者的近期对话,打开了一段从未分享给攻击者的私人聊天,并把其中一小段内容发到研究者控制的服务器。由于它直接调用 ChatGPT 自身的登录态 API,而不是去抓屏幕上的内容,其能力并不局限于聊天记录。研究者原话是:基本上可以对受害者账号执行任意操作。
Parameter 强调这是一次受控测试,没有发现真实环境中的利用,私聊读取的验证是在两个自有账号之间完成的。
影响评估
这个漏洞的价值不在单点危害,而在它揭示的模式:三个各自看起来合理的设计选择叠在一起,就形成了完整的越权链。
- MathLive 处理了会改变自身设置的消息,却没有校验发送方 frame。
- 这条消息被允许把原始 HTML 当作键盘布局数据携带。
- 这段 HTML 能创建一个未沙箱化、且继承 chatgpt.com 身份的 frame。
研究者特别指出,YouTube 那一步只是最后的变通手段,不是成因。即便封掉它,不受信任的 Preview 仍然可以把 HTML 推给主站。
修复建议
对 ChatGPT 用户而言不需要做任何事,修复在 OpenAI 服务端完成,无需安装或重置。对自建 AI 应用和前端团队,这次披露提供了几条可直接对照的检查项:
- 所有 postMessage 监听器强制校验 event.origin 与 event.source,不接受「任意来源」;对携带 HTML 的字段做白名单化处理。
- 动态创建的 iframe 显式设置 sandbox,不要依赖父页面同源带来的隐式信任。
- CSP 里允许的外部脚本域名越少越好。允许一个大平台域名,等于给攻击者留了一条可用信道。
- 富文本、图表、公式这类第三方渲染库,默认按「可能被诱导」来设计输入边界。