攻击只需要一次点击
Parameter 在 10 月 28 日的披露里写得很直接:攻击者创建一条恶意对话,用 ChatGPT 正常的分享功能发布,再把链接发给目标。受害者不需要安装 App、加入项目、粘贴代码或打开开发者工具,只要打开链接,载荷就会以 chatgpt.com 的身份运行,并拿到当前登录会话的权限。
研究人员确认,这段代码可以枚举受害者的会话列表、读取从未分享给攻击者的私密对话,并把内容发到外部服务器。它不只是改页面或弹窗,而是能直接调用 ChatGPT 的已认证接口。OpenAI 在 10 月 26 日修复,把报告定为 P1,支付 5,000 美元赏金。
七步链条
- 诱饵:分享一条包含真实交互图表和 HTML 区块的对话,图表会让页面加载 MathLive。
- 未上锁的门:MathLive 的 message 监听不校验发送方,接受带 HTML 的键盘布局更新。
- 落点:布局通过 keyboardContainer.innerHTML 渲染,createHTML 只是 Trusted Types 包装,不是消毒器。
- 同源继承:注入的 iframe srcdoc 没有 sandbox 属性,新框架继承了 chatgpt.com 的源。
- 绕过 CSP:CSP 允许 YouTube,载荷用 oembed 的 JSONP 回调把攻击者选的 JavaScript 当脚本执行。
- 拿令牌:以 chatgpt.com 身份读取页面里的 #client-bootstrap,取得 access token。
- 接管:用令牌调用会话接口,枚举、读取并外传私密对话。
不是 OpenAI 一家的毛病
研究者对 MathLive 0.100.0 的扫描标出 4 个没有发送方校验的 message 监听;当前版本 0.111.1 的主包里已不再命中。这个 bug 类的特征很固定:addEventListener('message', ...) 的回调里从不出现 event.origin 或 event.source。它可能藏在任何富文本编辑器、图表库、支付组件或客服 SDK 里。
今晚能做的自查
- 静态扫:搜 addEventListener('message' 与 onmessage =,逐个看回调有没有校验 origin/source。
- 动态验:在 DevTools 里从另一个源发一条合成 postMessage,看哪些监听会响应。
- 隔离:所有 srcdoc iframe 加 sandbox,能不给 allow-same-origin 就不给。
- 收口:CSP 禁止 JSONP 式回调,限制 connect-src 与 img-src 的外连域名。
- 分级:分享链接默认只读,涉及账号动作时要求重新认证。
这次链条里没有哪一个环节是“高级 0day”:未校验的监听、未加 sandbox 的 iframe、过宽的 CSP,单看都是常见问题。真正危险的是它们被组合在同一条分享链路里。对做 AI 产品的团队来说,模型安全之外,浏览器端的老问题仍然是账号接管最短的那条路。