ChatGPT не даёт печатать, пока Cloudflare не прочитает React-стейт — разработчик расшифровал механизм

Обложка: ChatGPT не даёт печатать, пока Cloudflare не прочитает React-стейт — разработчик расшифровал механизм

Каждый раз, когда вы открываете ChatGPT и ещё не успели ничего написать, в вашем браузере уже работает скрытая программа. Она читает состояние React-приложения, снимает отпечаток GPU, измеряет шрифты и сверяет геолокацию с данными сети Cloudflare — и только после этого разрешает вам нажимать клавиши.

Независимый исследователь безопасности под ником buchodi расшифровал 377 экземпляров зашифрованных программ Cloudflare Turnstile, которые ChatGPT запускает при каждом сообщении. Выяснилось, что система проверки ботов не ограничивается стандартным фингерпринтингом браузера — она также проверяет внутреннее состояние React-приложения, включая объекты __reactRouterContext, loaderData и clientBootstrap.

Ключевые выводы
• Cloudflare Turnstile в ChatGPT проверяет 55 свойств, сгруппированных в три слоя: браузер, сеть Cloudflare и состояние React-приложения.
• Шифрование программ — XOR с ключом, который лежит в том же HTTP-ответе. Это скрывает чеклист от беглого просмотра, но не от анализа.
• Помимо Turnstile, OpenAI запускает ещё два челленджа: поведенческую биометрию и Proof of Work на SHA-256.
• Граница приватности между пользователем и системой — вопрос политики, а не криптографии.

Как работает шифрование Turnstile

При каждом запросе к ChatGPT сервер отправляет поле turnstile.dx — около 28 000 символов base64, которые меняются при каждом обращении. Внешний слой XOR'd с токеном p из того же HTTP-обмена: оба значения путешествуют в одном запросе/ответе, поэтому расшифровка тривиальна.

После расшифровки внешнего слоя получается 89 VM-инструкций и внутри них — 19 КБ зашифрованного блоба с настоящей программой фингерпринтинга. Ключ для расшифровки этого блоба исследователь поначалу счёл эфемерным, пока не заметил его прямо в байткоде: в одной из инструкций пятым аргументом стоит float-литерал, сгенерированный сервером. Именно он является XOR-ключом. Проверка на 50 запросах: 50 из 50.

Три слоя: браузер, сеть, React-стейт

Расшифрованная программа собирает ровно 55 свойств — без вариаций по всем 377 образцам. Они делятся на три группы.

Слой 1: фингерпринт браузера

8 WebGL-параметров (производитель и модель GPU через UNMASKED_VENDOR_WEBGL и UNMASKED_RENDERER_WEBGL), 8 параметров экрана (colorDepth, width, height и другие), 5 параметров железа (hardwareConcurrency, deviceMemory, platform). Плюс — замер шрифтов: в DOM создаётся скрытый div с заданным шрифтом, измеряются реальные пиксельные размеры текста и элемент удаляется. Fingerprint сохраняется в localStorage под ключом 6f376b6560133c2c для повторного использования.

Слой 2: данные сети Cloudflare

5 edge-заголовков: cfIpCity, cfIpLatitude, cfIpLongitude, cfConnectingIp и userRegion. Эти значения инжектируются на стороне сервера на граничных узлах Cloudflare. Если запрос идёт напрямую к origin-серверу или через прокси за пределами сети Cloudflare — значения будут отсутствовать или не совпадут с фингерпринтом браузера.

Слой 3: внутренний React-стейт

Ключевая находка исследования: три React-свойства — __reactRouterContext, loaderData и clientBootstrap. Первое — внутренняя структура данных React Router v6+, прикреплённая к DOM. loaderData содержит результаты роутовых загрузчиков. clientBootstrap специфичен для SSR-гидрации ChatGPT.

Эти свойства существуют только если React-приложение ChatGPT полностью отрендерилось и гидратировалось. Headless-браузер, загружающий HTML без выполнения JS-бандла, их не создаст. Фреймворк-бот, который подделывает браузерные API, но не запускает React — тоже. Это детекция ботов на уровне приложения, а не браузера.

Ещё два скрытых челленджа Sentinel

Turnstile — лишь один из трёх челленджей в составе OpenAI Sentinel. Параллельно работают:

  • Signal Orchestrator (271 инструкция) — устанавливает слушателей событий keydown, pointermove, click, scroll, paste, wheel. Отслеживает 36 свойств window.__oai_so_*: тайминги нажатий, скорость мыши, паузы, паттерны прокрутки. Поведенческая биометрия в реальном времени.
  • Proof of Work — 25-полевой фингерпринт плюс SHA-256 hashcash. Сложность задачи — случайное число от 400 000 до 500 000. 72% решений укладываются менее чем в 5 мс. Включает 7 бинарных детект-флагов (ai, solana, InstallTrigger и другие) — во всех 100 проверенных образцах они равны нулю.

Приватность: вопрос политики, не криптографии

XOR-ключ для внутренней программы генерируется сервером и встроен в тот же байткод, который сервер же и отправил. Это значит, что Cloudflare расшифровать токен может всегда — ключ у них есть. Граница между данными пользователя и системным оператором определяется договорными обязательствами, а не математикой.

Обфускация выполняет реальные задачи: скрывает чеклист от статического анализа, не даёт OpenAI читать сырые значения фингерпринта без реверс-инжиниринга байткода, делает каждый токен уникальным (защита от replay-атак) и позволяет Cloudflare менять проверяемые свойства незаметно для внешних наблюдателей. Но «шифрование» XOR-ом с ключом из того же потока данных — это защита от беглого просмотра, не от анализа.

FAQ

Что такое Cloudflare Turnstile?

Cloudflare Turnstile — это альтернатива CAPTCHA для проверки, что запрос исходит от реального человека в реальном браузере, а не от бота. Вместо показа пользователю загадок с картинками Turnstile запускает в фоне зашифрованную программу, которая собирает фингерпринт окружения и генерирует токен для сервера.

Чем опасно чтение React-стейта?

Само по себе чтение __reactRouterContext и связанных объектов не несёт личных данных пользователя — это техническая структура SPA. Однако факт, что система верификации получает доступ к внутренностям конкретного приложения, поднимает вопросы: какие данные из этих объектов реально уходят в Cloudflare, изменится ли состав проверяемых свойств в будущем и есть ли у пользователей возможность это контролировать.

Можно ли обойти эту защиту?

Теоретически — только запустив настоящий браузер с полной гидрацией React-приложения ChatGPT. Подделка отдельных API и частичный рендер не пройдут третий слой проверки. Именно в этом и состоит ценность подхода с проверкой состояния приложения: он поднимает планку для автоматизации с уровня «браузерные API» до уровня «полноценное SPA».

Насколько надёжна методология исследования?

Исследователь указывает, что все данные получены от 32 добровольцев без несанкционированного доступа к чужим системам. 377 программ расшифрованы с точностью 100% — механизм детерминирован. SDK расшифрован и деобфусцирован вручную, весь анализ выполнен офлайн на Python. Обсуждение на Hacker News набрало 883 голоса и 576 комментариев, независимых опровержений методологии не поступало.

Выводы

Исследование наглядно показывает направление, в котором движется антибот-защита: от проверки браузерных API к проверке конкретного приложения. Для обычного пользователя это означает, что ChatGPT работает только в реальном браузере с полноценным запуском React. Для специалистов по безопасности — что обфускация через XOR с ключом из того же потока данных не является серьёзным криптографическим барьером. Для всех — что поведенческая биометрия (тайминги клавиш, движения мыши, паузы) собирается постоянно и в фоне, независимо от того, решаете ли вы CAPTCHA или просто пишете сообщение.