Claude Code のエージェントにデータを持ち出させない — サンドボックスのネットワーク分離と exfiltration リスク

Claude Code のサンドボックスは、既定では事前許可ドメインを持たず、新しいドメインへの接続ごとに確認を挟みます。allowedDomains で事前許可、deniedDomains で個別ブロック、managed 設定の allowManagedDomainsOnly で自動ロックダウンができます。ただし内蔵プロキシは既定で TLS を終端・検査しないため、クライアント申告のホスト名で許可判定します。この結果、github.com のような広いドメインを許すと domain fronting などでデータ持ち出し経路になりえます。本記事では、ネットワーク分離の設定、TLS の盲点、tlsTerminate とカスタムプロキシ、Unix ソケットの罠、そしてファイルとネットワークを両輪で締める原則を解説します。前回の sandbox.credentials 記事の対になる内容です。

前回、sandbox.credentials で「エージェントに秘密を読ませない」方法を扱いました。ですが読み取りを塞いだだけでは不十分です。もしエージェントが混乱・汚染された場合、手元のファイルを外部に持ち出す(exfiltration)経路が残っていれば、被害は防げません。だからこそサンドボックスは ファイルシステム分離とネットワーク分離を両輪で使う必要があります。本記事では、後者——「データを持ち出させない」ネットワーク分離を、設定と落とし穴の両面から整理します。

到達点

  • サンドボックスの既定ネットワーク挙動(事前許可なし・都度確認)を把握する
  • allowedDomains / deniedDomains と組織向けロックダウン
  • 内蔵プロキシの TLS の盲点と domain fronting による持ち出しリスク
  • tlsTerminate とカスタムプロキシの位置づけ
  • ファイル + ネットワークを両輪で締める原則

既定のネットワーク挙動

サンドボックスのネットワークは、サンドボックスの外で動くプロキシを通して制御されます。既定はこうです。

  • 事前許可ドメインは無い:最初にあるドメインへ接続が必要になった時点で、Claude Code が確認を出す
  • v2.1.191 以降:Yes を選ぶと、そのホストは現在のセッションの間許可され、以後同じホストへの接続では再確認されない
  • 制限はすべてのスクリプト・プログラム・サブプロセスに及ぶ

つまり既定でも「全開」ではなく、新規ドメインごとに人間が承認するモデルです。承認の手間を無くしたいなら allowedDomains で事前許可します。

allowedDomainsdeniedDomains

{
  "sandbox": {
    "enabled": true,
    "network": {
      "allowedDomains": ["*.github.com", "registry.npmjs.org"],
      "deniedDomains": ["gist.github.com"]
    }
  }
}
  • allowedDomains:Bash コマンドが到達してよいドメイン。ワイルドカード可
  • deniedDomains:広い allowedDomains のワイルドカードが許してしまうドメインを、個別にブロックする

*.github.com は許すが gist.github.com は塞ぐ」のように、許可の中に穴を開けない使い方ができます。

組織向けロックダウン

managed 設定で allowManagedDomainsOnly: true を置くと、非許可ドメインは確認を出さずに自動ブロックされ、managed 設定の allowedDomains のみが honored されます。開発者がローカルで許可ドメインを足しても効きません。無人運用や組織配布での確実な締めに使います。

最大の盲点:プロキシは TLS を見ていない

ここが本記事の核心です。内蔵プロキシは、クライアントが申告したホスト名に基づいて許可判定します。そして既定では TLS を終端・検査しません(暗号化された通信の中身を見ない)。

この帰結が domain fronting です。

プロキシは TLS を覗かずにホスト名だけで判定するため、サンドボックス内のコードが domain fronting 等の手法で、許可リスト外のホストに到達できてしまう可能性がある。

具体的な危険は、広いドメインの許可です。公式も警告しています——github.com のような広いドメインを許すと、データ持ち出しの経路を作りうる。攻撃者/汚染されたコードは、許可済みの広いドメインを踏み台に、実質的に外部へデータを送れてしまう。

教訓:allowedDomains必要最小限・具体的に。「とりあえず github.com」のような広い許可は、読み取りをいくら塞いでも持ち出しの裏口になります。

tlsTerminate とカスタムプロキシ

TLS の盲点に対する手立ては 2 段階です。

  • 実験的 network.tlsTerminate(v2.1.199+):内蔵プロキシが TLS を終端する。ただしこれは主に mask 認証情報の置換のためで、内容フィルタリングは追加しません。持ち出し対策そのものにはならない点に注意
  • カスタムプロキシ:脅威モデルが厳しいなら、TLS を終端して内容を検査する独自プロキシを立て、その CA 証明書をサンドボックス内に入れる。HTTPS の復号・検査、独自フィルタ、全リクエストのログ、既存セキュリティ基盤との統合が可能
{
  "sandbox": {
    "network": {
      "httpProxyPort": 8080,
      "socksProxyPort": 8081
    }
  }
}

「本当に持ち出しを止めたい」なら、内蔵プロキシの既定(ホスト名判定・TLS 非検査)では不十分で、TLS 検査するカスタムプロキシが要る——ここは割り切って設計します。

もう一つの罠:Unix ソケット

ネットワークは TCP だけではありません。allowUnixSockets で powerful なシステムサービスへのアクセスを不用意に許すと、サンドボックスを迂回されます。典型例が /var/run/docker.sock——これを許すと Docker ソケット経由でホストシステムへのアクセスを実質的に与えることになります。許す Unix ソケットは慎重に。

ファイルとネットワークは両輪

公式が明確に述べている原則です。

効果的なサンドボックス化には、ファイルシステム分離とネットワーク分離の両方が要る。ネットワーク分離が無ければ、汚染されたエージェントは SSH 鍵などの機密ファイルを持ち出せる。ファイルシステム分離が無ければ、システム資源にバックドアを仕込んでネットワークアクセスを得られる。

だから、既定を緩めるとき——allowWrite のパス追加、広い allowedDomainsexcludedCommands の例外——は、片側の緩和が反対側の制限を無効化していないかを必ず確認します。読み取りを sandbox.credentials で塞いでも、ネットワークが緩ければ意味が薄れる、という関係です。

実務レシピ

  1. 既定の都度確認を活かす:まずは事前許可を最小にし、必要なドメインだけ承認していく
  2. allowedDomains は具体的に:*.github.com より api.github.com。広いワイルドカードは避ける
  3. 穴は deniedDomains で塞ぐ:広い許可の中の危険ホストを個別ブロック
  4. 組織なら allowManagedDomainsOnly:managed 設定でドメインをロックし、開発者が広げられないようにする
  5. 厳しい脅威モデルなら TLS 検査プロキシ:内蔵プロキシの盲点(domain fronting)を、カスタムプロキシで塞ぐ
  6. Unix ソケットは最小限:docker.sock 等は原則許可しない
  7. 読み取り防御とセットで:sandbox.credentials の deny/mask と併用して初めて「読めない・持ち出せない」が揃う

注意点

  • サンドボックスは完全な隔離ではない:リスクを下げる層であって、TLS 非検査の既定では持ち出しを完全には防げません。強い保証が要るなら TLS 検査プロキシや、より強い隔離(コンテナ/VM)を併用
  • tlsTerminate ≠ 内容検査:TLS を終端するだけで、フィルタリングは別。持ち出し対策と混同しない
  • 広い許可は静かに危険:allowedDomains の広さは、承認プロンプトを減らす代わりに持ち出し面を広げるトレードオフ
  • サブエージェントも同じ設定:サブエージェント内の Bash も親のサンドボックス設定に従う

まとめ

読み取りを塞いでも、持ち出せるなら守れていない。サンドボックスのネットワーク分離は、既定では事前許可なし・都度確認で、allowedDomains/deniedDomains、組織向けの allowManagedDomainsOnly で締められます。ただし内蔵プロキシはホスト名判定・TLS 非検査が既定で、広いドメイン許可は domain fronting による持ち出し経路になりえます。本気で止めるなら TLS 検査するカスタムプロキシが要ります。

勘所は 3 つ — allowedDomains は必要最小限・具体的に、広い許可は持ち出しの裏口だと理解する、読み取り防御(sandbox.credentials)とネットワーク分離を両輪で締める。エージェントに自律的に Bash を任せるほど、「読めない」だけでなく「持ち出せない」まで設計して、初めて安心して任せられます。