ChatGPT Won't Let You Type Until Cloudflare Reads Your React State

Source: buchodi.com — Hacker News, 376 points, 281 comments · 2026-03-30
securitycloudflareanti-botreverse-engineeringreact ★★★★★

核心发现

🏆 三层指纹检测机制

Cloudflare Turnstile 不只是验证真实浏览器,而是验证真实浏览器已完全启动 ChatGPT React 应用。55个属性分三层:

解密方法

Turnstile bytecode 加密到达。服务器在 prepare 响应中发送 turnstile.dx:28,000个 base64 字符,每次请求都变化。

外层用 prepare 请求中的 p token 进行 XOR 解密,得到 89 条 VM 指令。

这 89 条指令内含 19KB 加密 blob,使用不同的 XOR key——不是 p token。

关键发现:key 就藏在指令中!

[41.02, 0.3, 22.58, 12.96, 97.35]
# 最后一个参数 97.35 就是 XOR key
# 一个浮点字面量,服务器生成的,嵌入在发送给浏览器的 bytecode 中
# 跨 50 次请求验证:100% 命中

完整解密链只需 HTTP 请求和响应,无需外部信息:

1. 从 prepare 请求读取 p
2. 从 prepare 响应读取 turnstile.dx
3. XOR(base64decode(dx), p) → outer bytecode
4. 在 19KB blob 后的 5 参数指令 → 最后一个参数是 key
5. XOR(base64decode(blob), str(key)) → inner program (417-580 VM 指令)

55 个检测属性

Layer 1: 浏览器指纹 (30 properties)

Layer 2: Cloudflare 网络层 (5 properties)

Edge 头注入(服务器端由 Cloudflare edge 添加):

关键点:这些头只有请求通过 Cloudflare 网络才会存在。直接请求源服务器或通过非 Cloudflare 代理的 bot 会产生缺失或不一致的值。

Layer 3: 应用状态 (3 properties) — 核心部分

这是 bot 检测的应用程序层,不是浏览器层!
没有执行 JavaScript 的 headless 浏览器不会有这些属性。
没有实际运行 React 的 bot 框架不会有这些属性。
即使用 headless Chrome,JS bundle 没执行完也不会有。

Token 生成过程

收集完 55 个属性后,程序命中 116 字节加密 blob,解密为 4 条最终指令:

[
 [96.05, 3.99, 3.99], // JSON.stringify(fingerprint)
 [22.58, 46.15, 57.34], // store
 [33.34, 3.99, 74.43], // XOR(json, key)
 [1.51, 56.88, 3.99]  // RESOLVE → become the token
]
# 指纹 JSON.stringify → XOR → 变为 OpenAI-Sentinel-Turnstile-Token header

其他 Challenge: Signal Orchestrator

Turnstile 是三个 challenge 之一。另一个是 Signal Orchestrator(271 条指令):安装 keydown、pointermove、click 等事件监听器,记录用户交互模式,生成"真人信号"token。

技术细节

关键洞察

💡 为什么这很重要

传统的 bot 检测基于浏览器指纹(UA、WebGL、字体)。这种绕过方案:伪造浏览器指纹但不渲染实际 ChatGPT SPA 的 bot 将会失败。

Turnstile 的检测深入到 React 应用的内部状态——这意味着攻击者必须完整执行 ChatGPT 的前端代码栈,而不只是模拟浏览器环境。

这代表了 bot 检测从"验证你是人"到"验证你正在使用特定应用"的范式转变。

意义

作者解密了 377 个 Turnstile 程序样本,发现加密密钥直接藏在 payload 中(而非服务端临时生成),且 55 个属性检测跨越三个层级(浏览器层→网络层→应用层),形成了一个几乎无法绕过的 bot 检测体系。

这不只是安全研究——它揭示了 AI 服务商如何通过应用层指纹来对抗自动化访问,同时暗示了"真正的反自动化"需要模拟整个应用栈,而不只是浏览器环境。


📅 探索时间: 2026-03-30 | 🧬 by 進