安全研究员 Jamie Larson(Buchodi)在自托管 Threat Intel 上发出一份完整复盘,记录下 OpenAI 是怎么通过内置在 bzr.openai.com 上的「广告收集器」拿到 ChatGPT 用户跨站行为画像的。机制并不隐蔽,关键变量只有一个:名叫 __obi 的 cookie。

三步把账号和浏览足迹绑在一起

复现过程在 Chrome for Android 上完成,作者用两套独立的抓包方法交叉验证,比对连续数月观察到的流量,覆盖 936 个广告像素、1029 个域名。

  • Step 1(签发 JWT):用户在 chatgpt.com 上时,客户端先生成 16 字节随机数,向 /backend-api/bazaar/obi/sync-token 发请求,后端返回 RS256 token,里面同时含 sub(账户 64 位 hex)和 obi(22 位标识符),绑定关系写死,60 秒过期。bzr 是 OpenAI 内部对广告平台「bazaar」的缩写。
  • Step 2(写跨站 cookie):客户端把 token POST 给 bzr.openai.com/v1/obi/sync,下行 Set-Cookie 是 Domain=.openai.com; HttpOnly; Max-Age=31536000; SameSite=None; Secure——SameSite=None 加 Secure 是跨站请求能带上 cookie 的标准配置,存活期一年。
  • Step 3(广告主送回):任何在 ChatGPT 上买广告的公司按 Meta / Google 的套路在自家站点加载 bzrcdn.openai.com/sdk/oaiq.min.js,脚本加载请求本身就附上 __obi,事件上报接口 /v1/sdk/events 也带。用户在 Chewy、Wayfair、HelloFresh、Coursera 等 13 个广告主域名上的浏览数据都会回流 OpenAI,挂回 ChatGPT 账户。

SDK 还抓回了什么

观察到的流量中,SDK 自动抓取的身份字段是广告主主动传入的 2.7 倍(685 vs 255)。tag-manager 总线是邮箱字段的最大来源——SDK 会替换 window.dataLayer.push、读 adobeDataLayer,并从 gtm.js 的 l= 参数里反推被改名的 GTM 层。0.1.31 版本曾抓过姓名和地理信息,OpenAI 在 8 月 27 日把范围收窄。邮箱、手机号、姓名经 SHA-256 哈希后再传输;国家、地区、城市、邮编明文发送。

URL 只保留 origin + path,23929 次请求里没有一次带 query string,但 path 部分会跟随债务解决方案、医疗问诊、诉讼表单等敏感漏斗。

cookie 策略与边界

OpenAI 把 __obi 列在「Analytics cookies」下,一年有效期,作用域 chatgpt.com 与 openai.com,这一节只有 __obi 一条。OpenAI 把分析和营销分成两个独立开关:oai_consent_analytics 和 oai_consent_marketing,作者解码的每一个 token 都带着 consent_decision: analytics_allowed——只开分析、不开营销的用户也会被装上 __obi。同一次抓包里:oai-did、oaicom-stable-id 被 SameSite=Lax 拦截,oai-client-auth-info 和会话 cookie 因域不匹配被拒,只有 __obi 被送出。

边界要写明:仅在 Chrome for Android 上验证;Safari ITP 全局屏蔽第三方 cookie,iOS 任何浏览器都跑 WebKit,机制失效;约五次 ChatGPT 会话里只有一次触发 sync token;OpenAI 是否在服务端把 cookie 解析回账户,作者只观察到 collector 用 202 接收了事件;退出登录后 anonymous 主体最少持续 27 天;广告主看不到这个值,他们只是装了一个 conversion pixel,根本不知道访客被挂回了 ChatGPT 身份。

为什么这件事和 Meta 那套不一样

把登录账号、第三方 cookie、跨站转化归并到一个 profile,是 Meta 多年以前就建好的结构性等价物,机制本身是标准 adtech。问题在于它被装在一个 AI 聊天产品上:人会把不会发到社交网络的话讲给 ChatGPT,而 ChatGPT 正越来越多地代用户执行操作。把登录态绑到一个第三方 cookie,等于把对话上下文暴露给任何愿意买广告的网站。

作者 9 月 14 日把机制和两个问题(为什么把 __obi 划为 analytics cookie;如果用户只同意 analytics、不同意 marketing,是否仍会收到 __obi)发给 press@openai.comprivacy@openai.com。OpenAI Support 回复确认了咨询并表示会内部 review,但没有回答这两个问题。