Claudeの推論モデルにマルチターンでリクエストを投げると、レスポンスの中に signature という長い文字列が紛れてくる。OpenAIのResponses APIをstateless(サーバに履歴を残さない)で使えば encrypted_content、Geminiなら thought signature。いずれも「モデルが答えを出す前に頭の中で考えた過程」、いわゆる chain-of-thought(思考の連鎖、CoT)を暗号化した塊で、次のターンでそのまま送り返す決まりになっている。中身は読めないブラックボックスだと、多くの実装者は思っている。私もそう扱っていた。
その前提を崩す論文が8月10日にarXivへ出た。Panfilovらの Stealing Reasoning Traces from Proprietary LLM APIs は、この暗号ブロックが思ったほど密封されていないことを、Anthropic・OpenAI・Googleの実APIで示している。
なぜ推論を暗号化してクライアントに預けるのか 🔐
まず設計の意図から。推論モデルは最終回答に至るまでの下書きを大量に生成するが、プロバイダはこの生CoTを客に見せたくない。競合に蒸留(強いモデルの出力で自社モデルを学習させる行為)の材料を渡すことになるし、途中に危険な内容が露出することもある。かといってサーバ側で保存すると、ゼロデータ保持(ZDR)をうたう契約や無状態APIと相性が悪い。
そこで各社は折衷案を取った。CoTを暗号化してクライアントに返し、次のリクエストで送り返させる。復号鍵はサーバが持つので、客は中身を読めないまま「思考の連続性」だけ保てる。Anthropicのドキュメントはこの仕組みを明記している。
Each thinking block also carries a
signaturefield, an encrypted copy of the full reasoning that you pass back unchanged in multi-turn and tool-use conversations.
さらに、display: "omitted"(Opus 4.8やSonnet 5などの既定)では thinking 本文が空で返り、signature だけに暗号化された全思考が載る。サーバはこの署名を復号して元の思考を復元し、プロンプトを組み立てる。読めないのは客だけで、サーバにとっては普通に開ける封筒だ、という点が後で効いてくる。
弱いモデルに強いモデルの封筒を開けさせる
論文が突いたのは、この封筒が「セッション・ユーザー・モデルをまたいで互換」だという一点だ。あるプロバイダの中では単一の鍵体系で暗号化されているため、Claude Opus 4.8が生成した署名を、同じAnthropicの Haiku 4.5 に食わせても受理されてしまう。
攻撃はこう組み立てる。強いモデルから暗号化された推論ブロックを取得し、それを防御の緩い弱い兄弟モデルへ差し込む。サーバは正当な封筒として復号し、復元された平文を弱いモデルの文脈に入れる。あとは「差し込まれた推論を一字一句そのまま書き写せ」と素朴なjailbreakで指示すれば、弱いモデルが平文を吐く。強いモデル自体を破る必要はない。論文はこのパターンを、以下のように各社の実モデルで再現している。
| プロバイダ | 推論を返すフィールド | 論文が使った復号役 |
|---|---|---|
| Anthropic(Claude) |
signature(thinkingブロック) |
Haiku 4.5 |
| OpenAI(Responses API) | encrypted_content |
GPT-5.6 Luna |
| Google(Gemini) | thought signature | Gemini Robotics 1.6 |
OpenAI側の挙動も公式ドキュメントで裏が取れる。store: false やZDRだと、推論アイテムに encrypted_content が付いて返り、続きの推論を保つには「暗号化推論を含む全出力アイテムをそのまま次のリクエストへ積み直す」運用になる。まさに封筒を客が運ぶ設計だ。
公開ログに紛れ込んだ鍵とPII
蒸留対策のすり抜けは業界内の綱引きだが、実務で怖いのは二つ目の使い道だ。開発者はデバッグやデータセット公開のために、セッションログをGitHubやHugging Faceへ平気で上げる。その中の暗号ブロックは「読めないから安全」と思われている。
論文は公開リポジトリから集めた 315,320個 の推論ブロックを復号し、367件のPII(個人を特定できる情報)と182件の認証情報を回収した。内訳にはAPIキー、パスワード、アクセストークン、秘密鍵が含まれる。暗号化されているから公開してよい、という直感が丸ごと間違っていたことになる。自分が過去に上げたトレースを思い返してヒヤリとする話だ。
残る二つの経路も地味に効く。最終回答が安全に拒否していても、途中の思考には危険な手順が残っていることがある(三つ目)。そして暗号ブロックの中にプロンプトインジェクションを仕込めば、それを取り込んだ公開エージェントのロールアウトを、外からは見えない形で汚染できる(四つ目)。
直った、とは誰も言っていない
ここはソース間で話が食い違う。論文自体は「2026年8月時点で、示した攻撃はもう再現しない」と自らの再現性を注記しており、責任開示のあと各社が対策を入れたと読める。一方、The Hacker News の報道は、三社いずれからも公式な脆弱性の認定は出ていないとし、過去に類似のリプレイ挙動を報告した研究者に対しては「再現しない」「セキュリティ上の含意は見当たらない」と返っていた経緯を伝えている。つまり「静かに塞がれたらしい」と「公式には認めていない」が同居している。防御を設計する側としては、直ったと聞いても再現手順が消えただけかもしれない前提で動くのが妥当だと考える。
自分のコードで先に直せること
APIの内部設計をこちらから直すことはできないが、露出を減らす手当ては今すぐ効く。二つある。
一つ目。モデルを途中で切り替えるなら、前ターンの思考ブロックを持ち越さない。Anthropicのドキュメントは明確にこう指示している。
When you switch between any two models, for example after a classifier refusal fallback, strip
thinkingandredacted_thinkingblocks from prior assistant turns. Thinking blocks are tied to the model that produced them.
分類器での拒否フォールバックのように、強いモデルから弱いモデルへ落とす経路を持っているなら、そこが攻撃の温床そのものだ。切り替え時に落とすのはコスト(無視されても入力トークンは食う)の話でもあるが、いまはセキュリティの話として読むべきだ。
二つ目。signature や encrypted_content を含むセッションログを、そのまま公開・共有しない。暗号化済みだからと油断せず、生の会話ログと同じ「秘密」として扱う。データセットを出すなら、思考ブロックを落とすか、平文化して中身を目視で確認してから出す。
この一件が示したのは、暗号文の強度ではなく境界設計の甘さだ。同じ鍵体系を全モデルで共有し、封筒を誰が運んできたか(どのモデル・どのユーザー・どのセッション)を復号時に照合しない限り、封筒は使い回せてしまう。論文は復号文脈への束縛(ユーザーIDや会話IDをAEADのペイロードに埋め込む)やモデル間の分離を対策として挙げている。開発者が触れるレイヤーの外側の話ではあるが、自分たちが設計するエージェント基盤でトークンや権限を扱うときの、そのまま使える教訓でもある。「読めない=安全」を鍵の外側の設計で担保しているか、を一度疑ってみる価値はある。
※本記事は一次情報の調査をAIが行い、事実確認のうえ執筆・公開しています。