ChatGPTの入力欄に文字を打てるようになるまでの裏側で、Cloudflareのボット検知システム「Turnstile」がかなり複雑なチェックをしていた――そんな解析結果が公開されました。
今回明らかになったのは、ただの「人間かどうかの確認」ではなく、ブラウザの挙動、Cloudflareのネットワーク情報、さらにChatGPTアプリ自体の状態まで見ているという、なかなか本気度の高い仕組みです。
正直、これは面白いです。
「ボット対策」と聞くと、私はつい“画像を選ばせるやつ”くらいの軽いイメージを持ってしまうのですが、実際にはそんな生やさしいものではなく、かなり多層的で、しかも復号や難読化まで入った“仕掛けの塊”でした。
GIGAZINEが紹介しているのは、技術ブログ「Buchodi」による解析です。
対象は、ChatGPTが利用しているCloudflareのボット検知システム「Turnstile」。
Cloudflareは、サイトを守るためのCDNやセキュリティサービスで有名ですが、Turnstileはその中でも「これは人間の操作か、それとも自動化されたボットか」を見分ける仕組みです。
従来のCAPTCHAみたいに、ユーザーに面倒なパズルを解かせるのではなく、裏で静かに判定するのが特徴です。
でも今回の解析で、Turnstileは「静かに判定する」どころか、かなり多くの情報を見ていることがわかりました。
解析によると、Turnstileは単純なブラウザの指紋採取だけではありません。
以下の3つのレイヤーをまたいでチェックします。
しかも、チェックするプロパティは55個。
たとえば次のような情報です。
ここで出てくる「hydration」は、ざっくり言うと“サーバーから送られてきたHTMLに、JavaScriptがちゃんと命を吹き込んで動く状態になること”です。
つまり、ただページを開くだけではなく、ChatGPTの単一ページアプリとしてちゃんと完成しているかまで見ているわけです。
これ、かなり嫌らしいです。
というのも、ブラウザの指紋を偽装するボットは世の中にいますが、アプリ全体のレンダリング状態まで自然に再現するのはかなり難しいからです。
個人的には、ここがいちばん「よく考えてあるな」と思ったポイントでした。
Turnstileの内部プログラムは、そのままでは読めません。
受信時点で暗号化されていて、まずは別の通信でやり取りされるトークンを使って復号します。
ざっくり流れを書くと、こうです。
p を読むturnstile.dx を読むbase64decode(dx) と p をXORして外側のバイトコードを得るここで出てくる「XOR」は、2つのデータを“重ね合わせる”ような基本的な暗号処理です。
高校数学というより、情報のオン・オフをひっくり返すような単純な演算だと思えばだいたい合っています。

面白いのは、最初は「キーはperformance.now()から派生しているのでは」と考えられていたのに、実際にはVM命令の中に浮動小数点リテラルとして埋め込まれていたことです。
つまり、解析を難しくするために“動的に見せかけて、実は静的に隠してある”わけです。こういうひねりはセキュリティ系の解析でよくありますが、やっぱり読んでいてニヤッとします。
Buchodiの解析では、難読化の目的も整理されています。
「リプレイ攻撃」は、昔の正規通信を録音して、同じ内容を再送して悪用する手口です。
だから、毎回違うトークンにするのは理にかなっています。
ただし、解析結果を見る限り、この仕組みは“分析を面倒にする”効果は大きいものの、完全に見破れなくするものではないようです。
同じデータストリーム内でのXORである以上、ちゃんと観察すれば追跡できる、という話ですね。
このあたりはセキュリティの世界らしくて、私はかなり納得感がありました。
「絶対に破られない」仕組みではなく、「破るコストを上げる」仕組み。実運用ではそれが大事です。
今回の解析では、Turnstileだけでなく、Sentinelシステムに含まれる他のチャレンジも紹介されています。
Sentinelは、ボット対策のための複数の仕掛けを束ねたもの、というイメージでよさそうです。

これは、ユーザーの行動を見ます。
たとえば以下のようなイベントです。
そして、window.__oai_so_* のようなプロパティを監視して、キー入力の間隔やマウスの速度といった「行動バイオメトリクス」を追跡します。
行動バイオメトリクスというのは、簡単に言うと“人のクセ”です。
タイピングの間隔やマウスの動かし方って、機械の自動操作だとどうしても不自然になりやすい。そこを見ているわけです。
こちらは、計算を少しやらせるタイプの仕組みです。
25フィールドのフィンガープリントとSHA-256ハッシュキャッシュを組み合わせているとのこと。
PoWは、相手に少し計算負荷をかけることで、大量アクセスをしにくくする仕組みです。
ただ、解析によれば、7つのバイナリ検出フラグはサンプル全体で一貫してゼロだったそうで、これ単体が主役の防御ではない可能性もあるようです。
記事中には、解析結果のサマリーも出ています。

この数字だけ見ても、かなり複雑です。
特に、PoWが5ms未満で解けている割合が高いのは、「そこまで重い計算をさせる」ことが目的ではないのかな、と思わせます。
おそらく、これはあくまで“軽い足切り”か、ほかの判定と組み合わせるための補助線ではないか、と私は見ました。
今回の話で重要なのは、単に「ChatGPTがCloudflareを使っていた」ということではありません。
本質は、AIサービスの入り口でも、かなり高度な不正対策が当たり前になってきたという点だと思います。
AIサービスは、普通のWebサイト以上に自動化アクセスの価値が高いです。
大量スクレイピング、botによる自動利用、アカウント濫用、APIの不正消費など、守るべきものが多い。
だから、表面的なCAPTCHAでは足りず、ブラウザの状態、ネットワークの特徴、操作のクセまで含めて見る方向に進むのは自然です。
一方で、こうした仕組みが高度になるほど、一般ユーザーにとっては「なんで急に入力できないの?」という不透明さも増えます。
このバランスは難しいです。セキュリティを強くすると体験が重くなる。体験を軽くするとボットに荒らされる。
個人的には、Webサービスが今後ますますこの綱引きに苦労するんじゃないかと思います。
今回明らかになったTurnstileの内部構造を見ると、Cloudflareのボット検知はかなり多層的で、単純なフィンガープリント対策では済んでいないことがわかります。
さらにSentinel全体として、行動解析やPoWも組み合わせて、ボットをじわじわふるい落とす設計になっていました。
要するに、これは「人間らしさ」を雑に見る仕組みではなく、かなり丁寧に“本物のブラウザで、本物のアプリを、本物のユーザーっぽく動かしているか”を確認する仕掛けです。
面倒くさいけど、セキュリティの世界ではこのくらいしないと守りきれないのだろうな、というのが率直な感想です。
参考: ChatGPTのボット検知システム「Turnstile」の内部構造とSentinelチャレンジの全貌が明らかに - GIGAZINE