OpenAI广告Cookie关联用户跨站行为

OpenAI广告Cookie关联用户跨站行为。其部署的__obi Cookie将ChatGPT账户标识与第三方网站浏览活动绑定,涉及936个广告商像素及1029个主机名流量数据,实现跨站用户行为映射。

OpenAI 在其内部广告平台(bzr.openai.com)部署了一种名为 __obi 的 Cookie,该 Cookie 的范围设定为 .openai.com。其核心功能是将用户在 ChatGPT 上的账户标识与其在其他网站上的浏览活动进行关联。

__obi Cookie实现跨站身份关联

当企业在 ChatGPT 上投放广告时,会在其自有网站嵌入 OpenAI 的代码片段。一旦用户访问这些网站并加载了相关代码,__obi Cookie 便会连同页面数据(包括搜索的产品、阅读的文章及购买行为)一同发送至 OpenAI。这一机制使得 OpenAI 能够将第三方网站的用户活动直接映射到其 ChatGPT 账户体系。

经过在移动设备上的复现验证,并通过两种独立的数据捕获方法及数月内涵盖 1,029 个主机名下 936 个不同广告商像素的流量数据交叉核对,该机制的技术细节已被完整披露。

技术实现流程

第一步:生成并签署标识符

在 chatgpt.com 客户端,系统生成 16 个随机字节,并向后端接口 POST /backend-api/bazaar/obi/sync-token(未登录状态下使用 /backend-anon/)发起请求。后端返回一个 RS256 JWT(JSON Web Token),其中包含以下关键信息:

{
  "iss": "chatgpt-wadi",
  "aud": "bzr.openai.com",
  "purpose": "obi_sync",
  "operation": "set",
  "consent_decision": "analytics_allowed",
  "consent_policy_version": "user_granular_consent_v1",
  "sub": "«redacted: 64-hex account subject»",
  "subject_type": "account_user",
  "obi": "«redacted: 22-char identifier»",
  "exp": "«iat + 60s»"
}

这里的 bzr 是 bazar 的缩写,代表 OpenAI 内部广告平台;wadi 则是发行服务名称。该令牌将用户标识符绑定至收集器,有效期仅为 60 秒。

第二步:Cookie 植入

客户端随后向 bzr.openai.com/v1/obi/sync 发送跨站点 POST 请求,携带上述 JWT。服务器响应中设置如下 Cookie:

Set-Cookie: __obi=«redacted»; Domain=.openai.com; HttpOnly;
            Max-Age=31536000; Path=/; SameSite=none; Secure

SameSite=None 配合 Secure 属性允许该 Cookie 在跨站点请求中发送。Max-Age 设为一年(31536000 秒)。JWT 中的 obi 值与 Cookie 中的值保持一致。

第三步:数据回传

在装有 __obi Cookie 的设备上,从广告主页面发往 OpenAI 主机的三类请求均会携带该标识符:

请求类型 是否携带 Cookie 备注
GET bzrcdn.openai.com/sdk/oaiq.min.js 脚本自行加载时浏览器自动附加 Cookie
POST bzr.openai.com/v1/sdk/events (携带 obref) 转换事件上报
活动上报(无凭证路径) SDK 的特定代码路径
GET bzrcdn.openai.com/pixel-config/... 对照组,未携带 Cookie

值得注意的是,即使 SDK 存在忽略凭证的代码路径,浏览器仍会在加载 <script src> 标签时自动附加域匹配的所有 Cookie。这意味着只要加载了 OpenAI 的脚本,标识符即被披露。

伴随收集的身份信息

同一 SDK 还会从广告主页面收集身份识别信息。有效载荷分为四个来源:v 为广告主故意传递的值;fmhtjs 则分别由 SDK 从表单字段、页面文本和标签管理器总线中提取。

在观察到的流量中,SDK 自动提取的身份信息数量远超广告主主动提供的信息(685 事件对 255 事件)。标签管理器总线是电子邮件地址的最大来源。SDK 通过替换 window.dataLayer.push 函数、读取 adobeDataLayer 以及解析 gtm.js 脚本标签参数来定位重命名的 GTM 层。

当前版本可采集电子邮件和电话号码。在 8 月 27 日更新前,版本 0.1.31 还曾采集姓名和地理位置信息。传输前,电子邮件、电话和姓名经过 SHA-256 加密;国家、地区、城市和邮政编码则以明文形式传输。邮政编码是最常见的表单字段,在 28 个站点的 100 个事件中被观测到。

URL 在发送前被缩减为来源加路径。在 23,929 个观测数据点中,无一包含查询字符串。涉及的页面路径涵盖医疗状况、债务解决渠道及诉讼申请表等敏感领域。

已知设置的 881 个像素中有 638 个启用了自动匹配功能,包括所有观测到的信贷和贷款广告商。此功能由 OpenAI 广告管理器控制。密码、一次性代码、卡号、SSN、出生日期、病史、诊断及法庭字段被排除在采集范围之外。

专为跨站追踪设计的 Cookie

在相同的广告主页面请求中,其他 OpenAI Cookie 均被浏览器阻止,唯独 __obi 成功发送:

Cookie 名称 结果
无稳定身份标识 被阻止(同站宽松策略下)
oai-client-auth-info(会话 Cookie) 被阻止(域名不匹配)
__obi 成功发送

__obi 是唯一配置为 SameSite=None 的 OpenAI 标识符,明确旨在实现跨站追踪。

覆盖范围与匿名性

测试设备上,单个 __obi 值从 12 个商业网站被发送至 OpenAI,所有请求均返回 HTTP 202 状态码。在更广泛的流量分析中,30 个不同的 __obi 值里有 12 个出现在多个广告商之下,其中一个值出现在 10 个广告商下。

即便用户退出登录,该机制依然生效。在解码的 932 个同步令牌中,736 个标记为 account_user,196 个标记为 anonymous。匿名主体与账户主体同样具有稳定性:每台设备对应一个 ID,持续至少 27 天。

合规性与官方回应

OpenAI 的 Cookie 政策将 __obi 列在 chatgpt.com 和 openai.com 的分析 Cookie 部分,描述其为帮助了解服务性能和使用情况的工具,有效期一年。这是该部分的唯一条目。

OpenAI 将“分析”和“营销”作为两个独立的同意选项(oai_consent_analyticsoai_consent_marketing)。然而,所有解码的同步令牌均显示 consent_decision: analytics_allowed。这意味着即使拒绝营销同意而仅允许分析的用户,也会受到此追踪机制的影响。

媒体于 9 月 14 日向 press@openai.com 和 privacy@openai.com 发送了关于该机制的问询,重点质疑为何将 __obi 归类为分析 Cookie。OpenAI 支持团队确认收到调查并表示将在内部审查意见,但未回答具体问题。后续观察到的脚本负载变化发生在问询发出之后。

局限性与对比

本次观察基于 Android 版 Chrome 浏览器。Safari 的智能跟踪预防功能会阻止所有第三方 Cookie;iOS 上的 Chrome 运行在 WebKit 引擎上,因此该机制在任何 iOS 浏览器上均无法运行。桌面端 Chrome 尚未测试。

并非所有 ChatGPT 会话都会触发此机制。大约五分之一的会话生成了同步令牌,且移动端网络客户端完全不提供广告同步。按照上述步骤操作的用户可能不会看到附加 Cookie 的像素触发。

目前尚无证据表明 OpenAI 服务端实际完成了数据结合。HTTP 202 仅表示收集器接受了附带 Cookie 的事件。从设计上看,OpenAI 应在服务端将其解析至账户系统,但这一过程未被外部观测到。

Meta 几年前曾构建过类似结构:登录账户后,像素在第三方 Cookie 上触发。这种机制在社交网络产品中已是标准做法。但在 AI 聊天产品上运行此类追踪引发关注,因为用户往往向 AI 透露不会在社交平台发布的内容,且 AI 正越来越多地代表用户执行行动。

与之形成对比的是,广告商自身设置的另一个 Cookie __obref 不具备跨站能力。它设置在广告商自己的域名下,每个网站获得的值不同且无法互相查看。在观测到的 2,860 个 __obref 值中,有 2,828 个仅出现在单一广告商名下。广告商的脚本也无法读取 __obi,他们仅安装了转换像素,无从知晓访客正在解析 ChatGPT 的身份。

评论 0

0/500

评论需审核后展示,请文明发言

💬
还没有评论,来说两句

相关阅读