powered by TechFeed
表示モード
Deep Dive

Claude Codeがシステムプロンプトに「見えないUnicode文字」でユーザー環境を分類している可能性——バイナリ解析で浮上した実装の不透明さ

7月1日、thereallo.devが「Claude Code Is Steganographically Marking Requests」と題した記事を公開した。著者・組織名は明示されていないが、プライバシー調査を目的としたバイナリ解析を行う独立系リサーチャーによるものとみられる。記事では、Claude Codeがシステムプロンプト内に視覚的に判別困難なUnicode文字を埋め込み、ユーザー環境の情報をステガノグラフィ的に分類している可能性が、コードレベルの根拠とともに詳述されている。なお、本記事執筆時点でAnthropicによる公式見解や反応は確認されておらず、以下の内容はあくまで個人研究者によるリバースエンジニアリングの結果に基づくものである点を念頭に置いていただきたい。

7月1日、thereallo.devが「Claude Code Is Steganographically Marking Requests」と題した記事を公開した。著者・組織名は明示されていないが、プライバシー調査を目的としたバイナリ解析を行う独立系リサーチャーによるものとみられる。記事では、Claude Codeがシステムプロンプト内に視覚的に判別困難なUnicode文字を埋め込み、ユーザー環境の情報をステガノグラフィ的に分類している可能性が、コードレベルの根拠とともに詳述されている。なお、本記事執筆時点でAnthropicによる公式見解や反応は確認されておらず、以下の内容はあくまで個人研究者によるリバースエンジニアリングの結果に基づくものである点を念頭に置いていただきたい。


システムプロンプトに仕込まれた「見えないマーカー」

あなたのAPIリクエストに、あなたが書いていない文字が混入しているとしたら——。それがこの調査の出発点だ。

Claude Codeのバイナリ(バージョン2.1.196)を解析したところ、通常なら無害に見える日付文字列が、実は環境情報のキャリアとして機能している可能性が明らかになった。

Claude Codeがモデルに送るシステムプロンプトには、次のような日付文字列が含まれる。

Today's date is 2026-06-30.

この一文に対し、Claude Codeは2箇所をサイレントに書き換える

  1. Today's のアポストロフィ(')を、別のUnicode文字に置換する
  2. タイムゾーンが Asia/Shanghai または Asia/Urumqi の場合、日付区切りを - から / に変える

アポストロフィの置換ルールは次のとおりだ。

条件 使用される文字
通常 '(U+0027)
既知ドメイン \u2019(RIGHT SINGLE QUOTATION MARK)
AIラボキーワード \u02BC(MODIFIER LETTER APOSTROPHE)
両方に該当 \u2019(MODIFIER LETTER PRIME)

モノスペースフォントでは見分けがつかないレベルの差異だ。見た目には「普通の日付」でも、rawリクエストには分類情報が埋め込まれている。これがプロンプト・ステガノグラフィsteganography:秘密の情報を別のデータの中に知覚されないよう隠蔽する技術)である。

何をトリガーに、何を分類しているのか

このマーカーが発動する条件は ANTHROPIC_BASE_URL 環境変数の有無だ。公式エンドポイント(api.anthropic.com)を使っている場合や、この変数が未設定の場合は早期リターンし、通常の日付文字列が使われる。

カスタムベースURLが設定されていると、コードは以下を確認する。

  • システムのタイムゾーンが Asia/ShanghaiAsia/Urumqi
  • APIベースURLのホスト名が、内部リストに含まれる既知ドメインと一致するか
  • ホスト名に特定のAIラボキーワードが含まれるか

ドメインリストとキーワードリストはbase64+XORキー91でエンコードされてバイナリに埋め込まれている。XORによる難読化は暗号化ではなく、静的解析や文字列検索による単純な発見を防ぐための軽量な隠蔽手法だ。バイナリを直接読んでもリストの内容が判別しにくくなるが、鍵さえ分かれば誰でも復号できる。解読されたキーワードリストには以下が含まれる。

deepseek,moonshot,minimax,xaminim,zhipu,bigmodel,baichuan,stepfun,01ai,dashscope,volces

ドメインリストははるかに長く、中国の大手企業ドメイン(baidu.comalibaba-inc.combytedance.netなど)に加え、プロキシ・リセラー・ゲートウェイ系ドメインが多数含まれる。

cn, baidu.com, alibaba-inc.com, alipay.com, bytedance.net,
kuaishou.com, jd.com, bilibili.co, moonshot.ai,
anyrouter.top, claude-code-hub.app, proxyai.com, yunwu.ai ...

Anthropicの意図と「実装の歪さ」

記事はAnthropicの意図を推測している。APIリセラーの検出、不正なClaude Codeゲートウェイの特定、モデル蒸留攻撃への対処が目的と考えれば、カスタム ANTHROPIC_BASE_URL やDeepSeek・Zhipuといったキーワードを含むホスト名がシグナルになるのは理解できる。

モデル蒸留攻撃(distillation attack)とは、商用モデルのAPIに大量のリクエストを送り、その入出力ペアを使って小規模な独自モデルを訓練・模倣する手法を指す。利用規約違反となるケースが多く、商用モデルの無断複製として問題視されている。

ただし、実装方法は奇妙だ、と記事は指摘する。

Trust from real developers depends on the boring behavior.(開発者からの信頼は、「退屈な挙動」の積み重ねで成り立つ)

Claude Codeはファイルシステム・シェル・gitへのアクセス権を持つ。コードを読み、コマンドを実行し、ファイルを編集し、コミットをプッシュできる。開発者がそのリスクを受け入れているのは、透明性があるという前提があるからだ。それにもかかわらず、システムプロンプトに不可視のUnicode文字で分類ビットを埋め込み、ドメインリストをXOR難読化で隠すのは、開発者ツールとしての信頼と相反する。

さらに、このシグナルの回避は極めて容易だ。ホスト名を変える、タイムゾーンを変える、バイナリをパッチする、プロセスをラップする——本当に悪意ある攻撃者には機能しない。結果として、カスタムURLを使う「普通の開発者」(内部ゲートウェイ利用者、ローカルプロキシ、研究用セットアップなど)だけが意図せず分類される形になっている、というのが記事の見立てだ。

記事はこう結論づけている。

もしクライアントがカスタムAPIゲートウェイを検出したいなら、明示的に言えばいい。ドキュメント付きのテレメトリフィールドとして送ればいい。ポリシーを可視化すればいい。リリースノートに書けばいい。シグナルをシステムプロンプトに隠すことは、他のすべてのプライバシーに関する主張を信じにくくする。

繰り返しになるが、本件についてAnthropicは現時点で公式なコメントを出しておらず、この実装が意図的なものか、どのような目的で行われているかは確認されていない。


詳細はClaude Code Is Steganographically Marking Requestsを参照していただきたい。