March 30, 2026 · 5 min read

Someone Decrypted ChatGPT's Cloudflare Bot Detection — Here's What They Found

Every time you type a message in ChatGPT, a silent Cloudflare Turnstile program runs in your browser before your keystrokes register. A researcher just reverse-engineered 377 of these programs and found something that goes way beyond standard browser fingerprinting.

The TL;DR: Cloudflare doesn't just verify you're running a real browser. It verifies you're running a real browser that has fully booted the ChatGPT React application. If your bot doesn't render the actual SPA, it fails. Period.

How the Encryption Actually Works

The Turnstile bytecode arrives encrypted in a field called turnstile.dx — about 28,000 characters of base64 that change on every request.

The outer layer is XOR'd with the p token from the prepare request. Both travel in the same HTTP exchange, so decrypting it is straightforward. Inside sits a 19KB encrypted blob with a twist: the XOR key is embedded right in the bytecode instructions as a float literal.

The key is in the payload. A float like 97.35, generated by the server, sitting in the same data stream it's supposed to protect. Verified across 50 requests — 50 out of 50.

The full decryption chain requires nothing beyond the HTTP request and response itself. No secrets, no external keys. Just XOR operations on data that's already there.

The 55 Properties Being Checked

The decrypted program collects 55 properties across three layers. No variation across 377 samples. Every single time.

Layer 1: Browser Fingerprint

Layer 2: Cloudflare Network

These are injected server-side by Cloudflare's edge. A bot making direct requests to the origin server behind a non-Cloudflare proxy will produce missing or inconsistent values. It's a built-in authenticity check.

Layer 3: Application State (The Killer)

This is the part that changes the game. These properties only exist if the ChatGPT React application has fully rendered and hydrated. A headless browser that loads the HTML but doesn't execute the JavaScript bundle won't have them. A bot framework that stubs out browser APIs but doesn't actually run React won't have them.

Bot detection at the application layer, not the browser layer. You're not just spoofing a browser anymore — you're spoofing a fully-booted React app with SSR hydration complete.

The Behavioral Layer: Signal Orchestrator

Turnstile is one of three challenges. The Signal Orchestrator installs event listeners for keydown, pointermove, click, scroll, paste, and wheel. It monitors 36 window.__oai_so_* properties tracking:

A behavioral biometric layer running underneath the fingerprint. And there's also a Proof of Work challenge — 25-field fingerprint + SHA-256 hashcash — though 72% solve under 5ms, so it's mostly compute cost, not the real defense.

Why Builders Should Care

If you're building anything that interacts with AI APIs, scrapes web apps, or creates browser automations, this is a wake-up call:

The Numbers

Programs decrypted: 377/377 (100%)
Properties per program: 55 (identical across all samples)
Instructions per program: 417-580 (mean 480)
SO behavioral properties: 36
PoW solve time: 72% under 5ms

The full write-up by the original researcher goes even deeper — covering the custom VM with 28 opcodes, randomized float register addresses, and the entire encryption chain. Worth reading if you're into security.

Read the full analysis →

Building something? I document tools, techniques, and security deep-dives that actually matter. Check out more posts →