4 ポイント 投稿者 GN⁺ 2026-03-30 | 1件のコメント | WhatsAppで共有
  • ChatGPTでメッセージ送信時に Cloudflare Turnstileプログラム が実行され、ブラウザーフィンガープリントだけでなく Reactアプリケーションの状態 まで検査する
  • 復号されたプログラムは 55個の属性 を収集し、ブラウザー・ネットワーク・アプリケーションの3層に分かれた検証手順を実行する
  • Reactレンダリングが完了した実際のSPA環境でのみ通過可能で、ヘッドレスブラウザーや単純なボットのリクエストは失敗する
  • 収集されたフィンガープリントは暗号化されて OpenAI-Sentinel-Turnstile-Token に変換され、ここに Signal OrchestratorProof of Work モジュールが追加で動作する
  • 復号キーを知っているのはCloudflareサーバーだけであり、プライバシー境界が技術ではなくポリシーによって決まる構造である

ChatGPTのメッセージ送信時におけるCloudflare Turnstileの動作構造分析

  • ChatGPTのすべてのメッセージ送信時に ブラウザー内で Cloudflare Turnstileプログラム が自動実行される
    • ネットワークトラフィックから377個のTurnstileプログラムを復号した結果、一般的なブラウザーフィンガープリント収集を超えて Reactアプリケーションの状態まで検査 していた
    • 単純なブラウザーフィンガープリント偽装ボットは通過できず、ChatGPTのSPA(単一ページアプリケーション) を完全にレンダリングして初めて検証を通過できる

暗号化構造と復号過程

  • Turnstileバイトコードはサーバー応答の turnstile.dx フィールドで渡され、リクエストごとに28,000文字長のbase64文字列 として暗号化されている
    • 外側の暗号化層は p トークンとの XOR 演算で復号可能で、両者は同一のHTTPリクエスト内でやり取りされる
    • 復号結果は 89個のVM命令 で構成されたJSON形式のバイトコードである
  • 内部には 19KBサイズの追加暗号化ブロブ(blob) が存在し、このブロブは別の XOR キーで暗号化されている
    • キーはバイトコード内の floatリテラル値(例: 97.35) として含まれており、サーバーが生成してブラウザーへ送信する
    • 50回のリクエストすべてで、同じ方式により有効なJSONへの復号を確認した
  • 全体の復号手順は次の5段階で構成される
    1. リクエストから p トークンを読む
    2. 応答の turnstile.dx を読む
    3. XOR(base64decode(dx), p) → 外側のバイトコードを生成
    4. 19KBブロブの後ろにある5引数命令から最後の引数をキーとして抽出
    5. XOR(base64decode(blob), str(key)) → 内部プログラムを復号(417〜580命令)

復号されたプログラムの検査項目

  • 内部プログラムは 28個の命令語(opcode) を持つカスタムVMとして実行され、リクエストごとに浮動小数点レジスタのアドレスがランダムに変更される
  • 合計 55個の属性(property) を収集し、377個のサンプルすべてに同一の項目が含まれていた
  • Layer 1: ブラウザーフィンガープリント

    • WebGL関連8属性: UNMASKED_VENDOR_WEBGL, UNMASKED_RENDERER_WEBGL, WEBGL_debug_renderer_info など
    • 画面情報8項目: colorDepth, pixelDepth, width, height, availWidth, availHeight, availLeft, availTop
    • ハードウェア5項目: hardwareConcurrency, deviceMemory, maxTouchPoints, platform, vendor
    • フォント測定4項目: 非表示のdivを作成後、fontFamily, fontSize, getBoundingClientRect, innerText でレンダリングサイズを測定
    • DOM探索8項目: createElement, appendChild, removeChild, style, position, visibility, ariaHidden など
    • ストレージ5項目: storage, quota, estimate, setItem, usage
      • 結果を localStorage のキー 6f376b6560133c2c に保存し、ページ再読み込みをまたいで保持する
  • Layer 2: Cloudflareネットワーク

    • エッジヘッダー5項目: cfIpCity, cfIpLatitude, cfIpLongitude, cfConnectingIp, userRegion
    • これらの値はCloudflareネットワーク経由でのみ存在し、オリジンサーバーへ直接アクセスするボット では欠落または不一致が発生する
  • Layer 3: アプリケーション状態

    • React内部構造3項目: __reactRouterContext, loaderData, clientBootstrap
    • これらはChatGPTのReactアプリケーションが完全にレンダリングされ、SSRハイドレーションが完了した場合にのみ存在 する
    • HTMLだけを読み込む、JSバンドルを実行しないヘッドレスブラウザー、あるいはReactを実際には実行しないボットフレームワークは失敗する

トークン生成過程

  • 55個の属性を収集した後、プログラムは 116バイトの暗号化ブロブ を復号して4つの最終命令を実行する
    • JSON.stringify(fingerprint)storeXOR(json, key)RESOLVE
    • 結果値は OpenAI-Sentinel-Turnstile-Token ヘッダーに変換され、すべての会話リクエストに含まれる

Sentinelの追加構成要素

  • Turnstile のほかに2つの追加検証モジュールが存在する
  • Signal Orchestrator

    • 271命令で構成
    • keydown, pointermove, click, scroll, paste, wheel イベントリスナーを設置
    • window.__oai_so_* 属性36個を追跡し、キー入力タイミング、マウス速度、スクロールパターン、アイドル時間、貼り付けイベント などを監視する
    • フィンガープリント収集に加え、行動ベースの生体認証レイヤー として機能する
  • Proof of Work

    • 25フィールドのフィンガープリント + SHA-256 hashcash ベース
    • 難易度は400K〜500K範囲の一様乱数で、72%が5ms以下で解決された
    • ai, createPRNG, cache, solana, dump, InstallTrigger, data など7つのバイナリ検出フラグを含む(100サンプルすべて0)
    • 計算コストは追加するが、主要な防御手段ではない

トークンを復号可能な主体とセキュリティ上の意味

  • 内部プログラムの XOR キーはサーバーが生成してバイトコードに含めるため、turnstile.dx を生成したサーバーだけがキーを知っている
  • ユーザーとシステム運営者の間のプライバシー境界は、暗号学的制約ではなくポリシー上の判断 によって定義される
  • 難読化の目的は
    • フィンガープリント収集項目を静的解析から隠す
    • Webサイト運営者(OpenAI)が生のフィンガープリント値を直接読めないようにする
    • 各トークンを固有化して 再利用(replay) を防ぐ
    • Cloudflareが検査項目を変更しても外部から認識しにくくする
  • しかし暗号化は 同一データストリーム内のキーと XOR 演算 によって行われており、解析防止レベルの難読化 にすぎない

収集および分析統計

項目
復号されたプログラム 377/377 (100%)
観測されたユニークユーザー 32
プログラムあたりの属性数 55(すべて同一)
命令数 417–580(平均480)
XORキー(50サンプル) 41個
Signal Orchestrator属性 36個
Proof of Workフィールド 25個
PoW解決時間 72%が5ms以下

分析手法

  • 適法な手続きで収集されたトラフィック のみを使用
  • 個人ユーザーデータは公開されていない
  • すべてのトラフィックは 参加者の同意のもとで観測 された
  • Sentinel SDK(sdk.js, 1,411行)に対して 手動のデオブスケーションおよびオフライン復号 を実施
  • 復号はPythonを用いてオフライン環境で進められた

1件のコメント

 
GN⁺ 2026-03-30
Hacker Newsのコメント
  • こんにちは、私はOpenAIのIntegrityチームで働くNickです
    今回のチェックは、ボット、スクレイピング、詐欺などのプラットフォーム悪用防止のための保護措置の一部です
    無料ユーザーおよび未ログインユーザーにも引き続きアクセスを提供するため、GPUリソースを実際のユーザーに優先配分する目的があります
    ページ読み込み時間、最初のトークンまでの時間、ペイロードサイズなどを監視し、保護措置のオーバーヘッド最小化に注力しています
    大半のユーザーへの影響はごく小さく、ごく一部だけが多少の遅延を経験する可能性があります
    また、誤検知率を下げつつ悪用を難しくするための精度改善も継続的に評価しています

    • OpenAIがスクレイピングを悪用と見なしている点は興味深い
    • 最近は、必須サービスを使うためにあらゆるクライアント検証を許容するブラウザを1つ、追跡防止のための別のブラウザを1つ、という状況になっている
      Nickの説明は理解できるが、プライバシーと機能性のどちらかを選ばなければならない世界が今後も続くのか気になる
    • 関連する問題かは分からないが、長い会話ではChat UIのパフォーマンスが非常に悪くなる
      入力遅延、レンダリングの引っかかり、完全なフリーズまで起きる
      iPhone 16のSafariとMacBook Pro M3のChromeで同様に発生している
    • 新しいアカウントがコメントを2件だけ残しているが、本当に人間なのか、それともOpenAIを擁護するボットなのか疑わしい
      Cloudflareのプライバシー侵害ツールを回して結果を共有してみては、という半分冗談の提案もある
    • OpenAI関係者から直接回答が聞けるのはうれしい
      私はPro契約者で、チーム全体では毎月2,000ドル以上使っている
      しかし、VPN(Mullvad) を使うと、ログイン済みでもChatインターフェースが頻繁に切断されたりタイムアウトしたりする
      有料ユーザーなら、VPN使用の有無に関係なく安定して利用できるとうれしい
  • Cloudflareが「疑わしい」ブラウザやIPを理由に、Webをほとんど使えなくしているという不満
    Firefoxを使っているだけでCAPTCHA地獄に落ちたと表現している

    • Cloudflareの「疑わしい」の定義は拡大し続けている
      VPN、プライバシー重視ブラウザ、珍しいIP帯域など、プライバシーを重視するユーザーほどむしろ引っかかりやすい
      当のボットはこうしたフィルターを簡単に回避する
    • もしかするとネットワークから不明なWebトラフィックが出ていないか確認してみては、という提案
      自分はFirefoxを使っているが、見るのはせいぜい普通レベルのCAPTCHAだけだという
    • Firefox + Ublock Originの組み合わせで使っているが、CAPTCHAはほとんど見たことがない
      CGNATを無効にしているので、それが違いを生んでいるのか気になる
    • 支払い直後に15回連続でCAPTCHAを解かされた理不尽な体験を共有している
      銀行で本人確認は済ませているのに、サイトが人間かどうかを見分けられないのは理解しがたいという
  • OpenAIは未ログインユーザーにも無料のChatGPTを提供しているため、これを無料APIのように悪用されないよう守ろうとしているようだ

    • ログインの有無に関係なくこうした検証をしているのか気になる
      AndroidアプリではPlay Integrityチェックが動作するが、Claudeアプリはログインだけを要求し、この種の検証はない
    • ログインしなくてもChatGPTが動いた経験を共有している
      Cookieもアカウントもない状態で質問を入力したら返答が来て驚いたという
    • こうした保護はPro契約者の利用パターン保護という目的もある
      APIと比べてサブスクリプション料金ははるかに安いため、悪用防止が必要だ
      SPAのロードチェック程度は大きな障壁ではなく、それを認識している人ならすでに回避技術を持っている
      他社もそれぞれアンチボットシステムを構築している
    • 月20ドルでGPT‑5.2を使えるのはコストパフォーマンスが良すぎるので、いつか価格調整が来そうだ
    • copilot.microsoft.comも似たようなCloudflareベースの保護を使っているようだ
  • ChatGPTのReactアプリが完全にレンダリングされないと特定の属性が存在しない、という点が興味深い
    これはブラウザレベルではなく、アプリケーションレイヤーのボット検知という方式だ
    たいていの高度な検知システムはこう動いていると思っていたが、今回の発見に特別な意味があるのか気になる

  • 投稿者がなぜこの問題を重要視すべきなのか、もっと明確に説明してほしかった
    結局のところ、OpenAIはユーザーに公式のReactアプリを使ってほしいという話であり、それがなぜ問題なのかよく分からない

    • だからその記事はAIが書いたような質の低い記事に感じられたという
  • 技術的な観点では興味深い
    Turnstileは基本的にサイトごとの設定がないものだと認識しているが、OpenAIがどうやってTurnstileのデータを自社APIと結び付けたのか気になる

  • なぜボット運営者がただWindows 11 VM + Chromeを回さないのか理解できない、という意見
    メモリ重複排除を使えば50台のVMを同時に回せて、AWS基準でページロード1000回あたり1セント程度なので非常に安いという

    • すでにこうした機能をパッケージとして提供するサービスが数多くある
      IPローテーション、位置情報スプーフィング、言語設定、パーサー内蔵など選択肢は豊富で、乗り換えコストも低いため自前で構築する理由はあまりない
    • 実際、この種のVMベースのアプローチはコストがかかるため、ボット数を減らす抑止効果がある
      単純な手法よりはるかに高くつくからだ
    • スクレイピング関連のRedditコミュニティを見ると、ヘッドレスブラウザでアクセスを止められるとボット開発者たちは非常に不満を抱いている
      提案のようにWindowsではなくLinuxコンテナを使えば、もっと軽量で効率的だ
    • GPUパススルーなしでグラフィックアクセラレーションがうまく効くWindows 11 VMを簡単に動かす方法があるなら教えてほしい、という要望
  • ChatGPTが書いたような雑な記事だという批判

    • 「Webブログの伝統的な特徴は、下書きがひどすぎて言語モデルですら二度目の推敲が必要になることだ」と冗談を言っている
  • 2023〜2024年にKeepChatGPTという拡張機能を使っていた
    APIなしでもユーザーを装って動く方式が興味深かった
    その後、Geminiの登場と頻繁なエラーで使うのをやめたが、AIパネルを右側に移動するオプションは気に入っていた
    KeepChatGPT GitHubリンク

    • 自分はWinForms WebViewを使ってChatGPTにクエリを送り、JSONレスポンスを受け取る小さなヘルパーアプリを使っている
      この方式はOpenAIのアンチボットシステムにまったく引っかからない
  • Cloudflareとアプリ間の統合が、標準のTurnstileを超えたカスタム機能なのか、それともエンタープライズ専用なのか気になるという質問