最近、Claude Code をめぐって一つの議論が起きています。リバースエンジニアリングを行った人たちによると、一部バージョンの Claude Code は特定条件下でローカル環境情報を読み取り、その検出結果をサーバーへ送る system prompt にエンコードしている可能性がある、というものです。この仕組みは、目立つ telemetry フィールドを追加で送るのではありません。Today's date is 2026-06-30. のような、ごく普通に見える日付の一文を書き換える形だとされています。
公開議論で見るべきなのは、「アカウント停止」という結果だけではなく、検出フローそのものです。ローカルの AI コーディングツールが、追加のネットワークリクエストを増やさずに、クライアント環境の特徴を通常のリクエストへ混ぜ込めることを示しています。開発者にとっては、単なるアカウントリスクより重要な論点です。
この記事では、公開されたリバースエンジニアリング記事やコミュニティ議論で繰り返し出てくる技術的な細部だけを整理します。この種の分析は具体的なバージョンや解析結果に依存するため、以下は「公開報告で説明されている実装ロジック」として読むべきであり、公式の完全な説明ではありません。
まず流れを平易に言う
一言でまとめると、このロジックは「カスタム API アドレスを使っているかを見て、そのアドレスが特定リストのサービスに似ているかを見て、さらに PC のタイムゾーンを見て、最後に判定結果を日付プロンプトに隠す」というものです。
公開分析によると、おおまかな流れは次の通りです。
- Claude Code は起動時またはリクエスト送信前に
ANTHROPIC_BASE_URLを読む。 - この変数が存在しない、または公式の既定アドレスを指している場合、特殊なマーキングロジックは発火しない可能性がある。
- カスタム endpoint を指している場合、URL を解析して hostname を取り出す。
- クライアントは hostname を内蔵リストやキーワードルールと照合する。
- 同時にローカルタイムゾーンを読み、
Asia/ShanghaiやAsia/Urumqiのような対象タイムゾーンかを判定する。 - クライアントは単独のフィールドを追加せず、system prompt 内の日付文を書き換える。
- サーバーはリクエストを受け取ったあと、日付区切り文字とアポストロフィのコードポイントからクライアント環境のマークを読み取る。
この流れでいちばん分かりにくいのは 6 番目です。次のような分かりやすいフィールドを書くわけではありません。
|
|
代わりに、次のような普通のテキストへ情報を入れます。
|
|
普通に見ると、ただの日付です。実際に情報を運ぶのは、日付の / または -、そして Today's の中にある、ほとんど同じに見えるアポストロフィです。
擬似コードで書くと、おおよそ次のようになります。
|
|
この擬似コードで重要なのは具体的な関数名ではなく、順序です。まずローカル環境を読み、ローカルで判定し、最後に判定結果を prompt テキストへ書き戻す。ユーザーには普通のモデルリクエストに見えますが、サーバーには状態付きのリクエストとして見えます。
各ステップで何を検出しているのか
さらに細かく見ると、それぞれのステップで得る情報は複雑ではありません。ただし組み合わせると、かなり明確な環境プロファイルになります。
| ステップ | クライアントが読むもの | 何を判定するか | 結果を書き込む場所 |
|---|---|---|---|
| 環境変数を読む | ANTHROPIC_BASE_URL |
カスタム API endpoint を使っているか | 後続ロジックに入るかを決める |
| URL を解析する | hostname | endpoint がどの種類のドメインか | apostrophe のコードポイントに影響 |
| リストと照合する | ドメイン接尾辞、キーワード | 特定サービスや AI ラボ関連キーワードに当たるか | apostrophe のコードポイントに影響 |
| システムタイムゾーンを読む | ローカル timezone | 特定地域のタイムゾーンか | 日付区切り文字に影響 |
| プロンプトを書き換える | 日付文 | 前段の判定結果をエンコードする | system prompt |
つまり単一のシグナルだけで判断しているわけではありません。ANTHROPIC_BASE_URL は入口にすぎず、hostname とタイムゾーンが後続の分類材料になり、最後に system prompt が結果を運ぶ場所になります。
トリガー:ANTHROPIC_BASE_URL
公開分析で最初に挙げられているのは、環境変数 ANTHROPIC_BASE_URL の読み取りです。
この変数は通常、Claude Code が公式 api.anthropic.com へ直接リクエストするのではなく、カスタム API endpoint、企業ゲートウェイ、プロキシサービス、または Anthropic API 互換の中継サービスを使うために設定されます。つまり、この変数そのものは悪意ある設定ではありません。多くのチームは、ネットワーク、コンプライアンス、監査、統一認証、コスト管理のためにカスタムゲートウェイを使います。
公開されたリバースエンジニアリング分析によると、このロジックは全リクエストに無条件で発火するわけではありません。非デフォルトの API base URL が設定されていることを検出してから、後続の判定へ進むとされています。これは重要です。「公式へ直接接続する通常ユーザー」と「カスタム endpoint を使うユーザー」をまず分け、後者に対してより細かい環境識別を行う形だからです。
流れとしては、おおよそ三層に分けられます。
ANTHROPIC_BASE_URLが設定されているか。- その URL の hostname が特定のドメインやキーワードリストに当たるか。
- ローカルタイムゾーンが特定地域に属するか。
このため、議論は Claude Code のようなローカル開発ツールに集中します。ユーザーのマシン上で動作するため、ローカル環境変数、タイムゾーン、設定ファイル、shell コンテキストを自然に読めるからです。
第 1 ステップ:カスタム endpoint の hostname を取り出す
ANTHROPIC_BASE_URL が存在する場合、クライアントはそれを URL として解析し、hostname を取り出せます。
たとえば:
|
|
実際に照合対象になるのは、通常は完全な URL ではなく、次の部分です。
|
|
これには二つの効果があります。
第一に、パス、query string、具体的な API バージョンは重要ではなく、ドメイン本体だけを見ればよくなります。第二に、各サービスが API path をどう設計しているかを気にせず、ドメインやキーワードのリストを再利用できます。
公開議論では、このリストはコード内に平文で置かれているのではなく、難読化またはエンコードされた状態で保存され、実行時にデコードして照合されるとされています。これが必ず悪意を意味するわけではありませんが、普通のユーザーが文字列検索でルールを見つけにくくなるのは確かです。
第 2 ステップ:システムタイムゾーンを確認する
もう一つ繰り返し言及されているシグナルは、システムタイムゾーンです。
公開分析では、検出ロジックが次のようなタイムゾーンに注目するとされています。
|
|
タイムゾーンは微妙なシグナルです。ネットワークリクエストも IP アドレスも不要ですが、ユーザーの地域や長期的なシステム利用習慣を大まかに示せます。多くの開発者はネットワーク経路を切り替えても、PC のタイムゾーンまでは変更しません。カレンダー、ログ、ビルドタイムスタンプ、日常利用に影響するからです。
クライアントが IP だけを見るなら、ユーザーはプロキシ、企業出口、クラウド環境の背後にいるかもしれません。ローカルタイムゾーンも見ると、もう一層のローカル環境判定が加わります。
第 3 ステップ:ドメインリストとキーワードを照合する
タイムゾーンに加えて、公開分析では二種類の hostname 照合も言及されています。
- 特定ドメイン、ドメイン接尾辞、サービス事業者リストに当たるか。
- AI ラボ、モデルサービス、関連企業に関するキーワードを含むか。
この照合の目的は、単に「中国ユーザーか」を判断することではない可能性があります。通常のカスタムゲートウェイ、地域関連 endpoint、AI ラボ関連 endpoint、複数条件の同時命中といったリスクタイプを分けるためかもしれません。
そのため、後続のエンコードには複数の状態が必要になります。もし「命中/未命中」だけを表したいなら二値のマークで十分ですが、公開分析で言及されている Unicode 文字置換は、より多くの組み合わせを表せます。
重要な手法:結果を system prompt に書き込む
最も議論を呼んでいるのは、検出結果が明示的なフィールドとしてアップロードされるのではなく、system prompt の日付文にエンコードされる点です。
Claude Code のリクエストには、もともと次のようなシステム情報が含まれます。
|
|
公開分析によると、クライアントはリクエスト送信前にこの文を二種類の方法で変更します。
一つ目は日付区切り文字です。特定タイムゾーンを検出すると、日付が次の形から:
|
|
次の形に変わる可能性があります。
|
|
二つ目は Today's の apostrophe を置き換えることです。目にはすべてアポストロフィに見えますが、Unicode コードポイントが異なります。たとえば:
|
|
表示上は非常に近いですが、プログラムから見ると完全に別の文字です。サーバーは Today と s date is の間にある文字のコードポイントを確認するだけで、クライアントがエンコードした状態を読み取れます。
より直感的には、これは「暗号表」のようなものです。
| 表示 | Unicode | おおよその意味 |
|---|---|---|
' |
U+0027 |
通常の ASCII apostrophe、特定条件に未命中 |
’ |
U+2019 |
特定のドメインまたは接尾辞リストに命中 |
ʼ |
U+02BC |
AI ラボ関連キーワードに命中 |
ʹ |
U+02B9 |
複数条件に同時命中 |
この表は検出回避を教えるためのものではありません。なぜ肉眼で見つけにくいのかを説明するためです。四つの文字はいずれもアポストロフィに見えますが、コードポイントは完全に異なります。ログ、ターミナル、Web フォントで描画されると、違いはさらに分かりにくくなります。
そのため、多くの人はこれを prompt steganography、つまり正常に見えるプロンプトテキストの中へ情報を隠す手法と呼んでいます。
なぜこのマークは目立ちにくいのか
この方法が目立ちにくい理由は主に三つあります。
第一に、追加リクエストが不要です。パケットキャプチャを見ても、独立した「環境情報アップロード」エンドポイントは見えません。リクエストは通常のモデル呼び出しのままです。
第二に、目立つフィールドが不要です。JSON を調べても、普通の system prompt に見えるかもしれません。Unicode コードポイントを 1 文字ずつ比較しなければ、アポストロフィの差は見落としやすいです。
第三に、ユーザーが system prompt にあまり注意を払わないことを利用しています。開発者は通常、自分の prompt、ツール呼び出しパラメータ、token 消費、モデル出力を見ます。クライアントが自動で組み込む system context を 1 文字ずつ確認することはほとんどありません。
エンジニアリングとしては賢い仕組みです。しかし信頼の観点ではかなり敏感です。ユーザーが Claude Code にローカル端末で動く権限を与えるのは、コードの読み書き、コマンド実行、開発支援のためであり、ローカル環境の特徴を見えない形でリクエストにエンコードするためではありません。
サーバーはどうやって読むのか
公開分析が正しければ、サーバー側でこのマークを読むのは難しくありません。
受信後に確認するのは二点だけです。
- 日付が
-を使っているか/を使っているか。 Today'sの中の apostrophe がどの Unicode 文字か。
もっと身近に言えば、クライアントが送っているのは「普通の書類」ですが、日付形式とアポストロフィの形に二つの小さなメモが挟まっているようなものです。
たとえば通常のリクエストは次のように見えます。
|
|
特定タイムゾーンに命中すると、次のようになる可能性があります。
|
|
特定の endpoint に命中すると、アポストロフィが別の Unicode 文字になることがあります。肉眼では次のように見えるかもしれません。
|
|
しかしプログラムが読む文字は同じ ' ではありません。サーバーは文全体を理解する必要はなく、二つの位置の文字を取り出すだけでマーク状態を復元できます。
その結果、リクエストを次のような状態に分類できます。
- 特定リストに未命中
- 特定のドメインリストに命中
- AI ラボ関連キーワードに命中
- 複数条件に同時命中
- システムタイムゾーンが特定地域に属する
つまり本当の「報告フィールド」は region、proxy、risk_flag という名前ではありません。自然言語の system prompt に含まれる文字差分の中に隠れています。
普通のリスク管理と何が違うのか
サービス事業者がリスク管理を行うこと自体は不思議ではありません。API の悪用、アカウント転売、モデル蒸留、異常な並行実行、地域ポリシー違反は現実の問題です。問題は透明性と境界です。
一般的なリスク管理は理解しやすいものです。ログイン IP、支払い地域、リクエスト頻度、デバイス情報、組織アカウント、API key の利用パターンなどです。これらのシグナルも敏感ですが、ユーザーはプラットフォームが安全判断に使うことをある程度予想できます。
今回の論点は違います。もしクライアントが本当にローカルタイムゾーンやカスタム endpoint の命中結果を system prompt に隠してエンコードしているなら、ユーザーは製品 UI、リクエストフィールド、release notes からそれを知るのが難しい。ファイルシステムと shell 権限を持つ開発ツールでは、これは信頼に直結します。
開発者が注目すべきこと
この種の出来事から得られる教訓は、単に「特定のツールを使うな」ではありません。ローカル Agent の信頼境界を見直すことです。
注目すべき点はいくつかあります。
- ローカル CLI が環境変数、設定ファイル、タイムゾーン、システム言語などの環境情報を読むか。
- 自動生成される system prompt を閲覧、エクスポート、監査できるか。
- リクエスト送信前の最終 payload をユーザーが確認できるか。
- release notes が新しい検出、リスク管理、telemetry ロジックを説明しているか。
- 企業ゲートウェイが上流リクエスト内容を記録、監査できるか。
- ローカルツールが telemetry や敏感な環境読み取りを無効にする選択肢を提供しているか。
AI コーディングツールがプロジェクトファイルを読み書きし、shell コマンドを実行し、git にアクセスし、環境変数を読めるなら、本質的には「高権限のローカル代理」に近い存在です。この種のツールには、通常のチャット Web ページより高い透明性が必要です。
結論
今回の Claude Code リクエスト透かし疑惑で本当に議論すべきなのは、あるアカウントが停止されたかどうかではありません。クライアントが環境情報を通常のリクエストへどうエンコードするのかです。
公開されたリバースエンジニアリング分析によれば、この流れはおおよそ次の通りです。ANTHROPIC_BASE_URL を読み、hostname を解析し、ドメインとキーワードリストに照合し、システムタイムゾーンを確認し、日付区切り文字と Unicode apostrophe を使って結果を system prompt に書き込む。全体として追加のネットワークリクエストも、新しい明示フィールドも必要ありません。
もしこれが反悪用のリスク管理の一部だとしても、サービス提供側は境界をより透明に説明すべきです。開発者がローカル Agent に与える権限が大きいほど、それが何を読み、何を書き換え、何を送るのかを知る必要があります。
AI コーディングツールの能力が強くなるほど、信頼の問題は「とりあえず信じる」だけでは解決できません。