Как это работает

Шаг 1. ChatGPT создает идентификатор и подписывает его.

На странице chatgpt.com клиент генерирует 16 случайных байт и отправляет POST /backend-api/bazaar/obi/sync-token (или /backend-anon/ при выходе из аккаунта). Backend возвращает RS256 JWT:

{
  "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»"
}

sub — это аккаунт. obi — идентификатор. Токен их связывает, ограничивает область действия сборщиком и истекает через 60 секунд. bzr — сокращение от bazaar, внутреннее название платформы объявлений OpenAI; wadi — сервис-издатель.

Шаг 2. Идентификатор становится cookie на домене OpenAI.

Клиент отправляет POST {"token": "«JWT»"} кросс-сайтовый запрос на bzr.openai.com/v1/obi/sync. Ответ:

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

SameSite=none с Secure — конфигурация, необходимая cookie для отправки в кросс-сайтовых запросах. Max-Age равен одному году. Значение obi в JWT и значение в cookie идентичны.

Шаг 3. Сайты рекламодателей отправляют cookie обратно.

Три класса запросов идут со страницы рекламодателя на хосты OpenAI. На телефоне с __obi в хранилище cookie все три несли его:

Запрос Нёс __obi Примечания
GET bzrcdn.openai.com/sdk/oaiq.min.js да сама загрузка скрипта
POST bzr.openai.com/v1/sdk/events с obref да события конверсии
POST bzr.openai.com/v1/sdk/events, пустое тело да путь SDK без учётных данных
GET bzrcdn.openai.com/pixel-config/… нет заголовка cookie контрольный запрос

Первая строка особенно интересна. Пиксель SDK имеет путь кода, который пропускает учётные данные, и это не помогает: браузер присоединяет cookie к запросу <script src>, который загружает SDK, ещё до выполнения какого-либо кода OpenAI. Просто загрузив тег, идентификатор раскрывается.

Какие данные передаются с ним

Тот же SDK также собирает информацию о личности со страницы рекламодателя. Полезная нагрузка разделяет четыре источника, помеченные самой OpenAI: in для значений, которые рекламодатель передаёт специально, и fm, ht, js для значений, которые SDK извлекает из полей форм, отрисованного текста страницы и шины диспетчера тегов. В наблюдаемом трафике извлечённая личная информация превышала информацию, предоставленную рекламодателем, в соотношении 685 событий к 255.

Шина диспетчера тегов — крупнейший источник адресов электронной почты. SDK заменяет window.dataLayer.push собственной функцией, также читает adobeDataLayer и находит переименованные слои GTM, парся параметром l= со скрипт-тега gtm.js. Текущие версии берут из неё адрес электронной почты и номер телефона. Версия 0.1.31 также брала имена и географию, прежде чем область была сужена 27 августа.

Адреса электронной почты, номера телефонов, имена и фамилии хешируются SHA-256 перед отправкой. Страна, регион, город и почтовый индекс отправляются в открытом виде. Почтовый индекс был наиболее собираемым полем формы — 100 событий на 28 сайтах.

URL сокращаются до источника плюс путь перед отправкой; ни один из 23 929 наблюдаемых не нёс строку запроса. Пути сохраняются, и пути, достигшие сборщика, включали медицинское состояние, воронку решения долговых проблем и форму приёма судебных исков.

Автоматическое совпадение было включено для 638 из 881 пикселей с известной настройкой, включая каждого рекламодателя кредитных и кредитных услуг, который наблюдался. Это контролируется из Менеджера объявлений OpenAI. Список запретов исключает пароли, одноразовые коды, номера карт, SSN, дату рождения, медицинскую историю, диагноз и поля суда.

Cookie создан для работы кросс-сайтово

На тех же запросах к странице рекламодателя все остальные cookie OpenAI блокировались браузером:

Cookie Результат
oai-did, oaicom-stable-id заблокирована, SameSite=Lax
oai-client-auth-info, session cookies заблокирована, несовпадение домена
__obi отправлена

__obi — единственный идентификатор OpenAI, настроенный с SameSite=None.

Наблюдаемый охват

На устройстве одно значение __obi было отправлено OpenAI с 12 коммерческих веб-сайтов под 13 различными ID пиксель, включая Chewy, Wayfair, ThriftBooks, Eventbrite, HelloFresh, Coursera и SeatGeek. Каждый запрос был принят с кодом 202.

В более широком трафике 12 из 30 различных значений __obi появились под более чем одним рекламодателем, одно — под десятью.

Это работает, когда вы вышли из аккаунта

Из 932 декодированных токенов синхронизации 736 содержали subject_type: account_user и 196 содержали anonymous. Анонимный субъект столь же стабилен, как и субъект аккаунта: по одному на устройство, сохраняясь как минимум 27 дней.

Что говорит политика cookie OpenAI

В политике cookie OpenAI __obi указан в разделе «Аналитические cookie», один год, на доменах chatgpt.com и openai.com. Это единственная запись в этом разделе. Политика описывает аналитические cookie как помогающие OpenAI понять, как работают её сервисы и как их используют.

OpenAI разделяет аналитику и маркетинг на два отдельных выбора согласия — oai_consent_analytics и oai_consent_marketing, и каждый декодированный токен синхронизации содержал consent_decision: analytics_allowed. Кто разрешает аналитику и отказывает в маркетинге, получает это.

Ответ OpenAI

Механизм и два вопроса были отправлены на press@openai.com и privacy@openai.com 14 сентября: почему __obi классифицируется как аналитический cookie и получает ли пользователь, предоставивший согласие на аналитику и отказавший в маркетинге, этот cookie. Ответ пришёл из служба поддержки OpenAI. Она подтвердила получение запроса, сказала, что наблюдения будут переданы для внутреннего рассмотрения, и не ответила ни на один вопрос. Наблюдение о загрузке скрипта было сделано после отправки запроса. Пост будет обновлён, если OpenAI ответит.

Ограничения

Браузеры. Наблюдали на Chrome для Android. Safari Intelligent Tracking Prevention блокирует все сторонние cookie, а Chrome на iOS работает на WebKit, поэтому механизм не работает ни в каком браузере iOS. Desktop Chrome не тестировался.

Шлюзирование. Примерно одна сессия ChatGPT из пяти создавала токен синхронизации. Мобильный веб-клиент ChatGPT показывает объявления без синхронизации вообще. Кто-то, следующий нижеприведённым шагам, может увидеть срабатывание пикселя без прикреплённого cookie.

Присоединение не наблюдается. 202 означает, что сборщик принял событие с прикреплённым cookie. То, что OpenAI разрешает его на сервер аккаунтов, следует из дизайна; мы не наблюдали это.

Meta построила структурный эквивалент годы назад. Вошедший в систему аккаунт, сторонние cookie при срабатывании пикселей, внесайтовые конверсии, разрешённые профилю. Механизм — стандартная рекламная технология. Что не имеет прецедента — запуск этого в продукте AI-чата. Люди рассказывают этим продуктам вещи, которые не выложили бы в социальную сеть, и эти продукты всё чаще действуют от их имени.

Другой cookie пикселя этого не делает. __obref устанавливается в собственном домене рекламодателя. Каждый сайт получает другое значение, и ни один сайт не может видеть другого. Из 2 860 наблюдаемых значений 2 828 появились ровно под одним рекламодателем.

Рекламодатели не могут это видеть. __obi принадлежит домену, который их скрипты не могут читать. Они установили пиксель конверсии и не имеют способа узнать, что их посетители разрешаются в ChatGPT идентичность.

Screenshot демонстрирующий механизм отслеживания