MCPサーバーのサンドボックス化とは?ローカル/リモートMCPをファイル・秘密情報・通信から隔離する方法【MCP Security 2026】
MCPサーバーのサンドボックス化を解説。MCP仕様2026-07-28版の要求、被害を抑えられた4つのCVE、プロセスサンドボックス・コンテナ・gVisor・microVMの比較、srtの検証結果(既定では.envが読めた)、Dockerの堅い設定、15項目のチェックリスト。
最終更新:2026年10月19日 / 対象:MCP仕様 2026-07-28版(Security Best Practices:Local MCP Server Compromise、stdio Transport Security in Proxy Scenarios)、Anthropic Sandbox Runtime 0.0.80、Docker MCP Toolkit / Gateway、gVisor、Firecracker
結論(30秒で読める要約)
MCPサーバーのサンドボックス化とは、MCPサーバーを隔離された境界の中で動かし、悪意のある・バグのある・乗っ取られたサーバーでも、本当に必要なファイル、秘密情報、通信先、CPUにしか触れられないようにすることです。何もしなければ、ローカルのMCPサーバーはMCPクライアントと同じ権限で動くため、SSHの秘密鍵も .env も、あなたのユーザーが読めるものはすべて読めてしまいます。
MCP仕様(2026-07-28版)はこのリスクを「Local MCP Server Compromise」として名指しし、クライアントはMCPサーバーのコマンドを「最小限の権限のサンドボックス環境で実行すべき(SHOULD)」としています。MCP Securityの実務としては、次の5点に集約できます。
- 信頼度に応じて隔離レイヤーを選ぶ。信頼しているが閉じ込めたいサーバーはOSのプロセスサンドボックス(Anthropicの
srt、Seatbelt、bubblewrap)、サードパーティ製はコンテナ、他人のコードを動かすならgVisorかFirecrackerなどのmicroVM。 - ファイルとネットワークは必ずセットで制限する。ファイルだけ絞っても、読めたものは外へ送れます。Anthropic自身も「効果的なサンドボックスにはファイルとネットワークの両方の隔離が必要」と明言しています。
- 秘密情報の読み取りは明示的に禁止する。今回の検証(7章)では、
srtは書き込みを既定で拒否しましたが、読み取りは既定で許可のため、denyReadに入れるまでファイルシステムMCPサーバーが.envを読めました。 - サーバー自身のパスチェックを「壁」と思わない。公式のファイルシステムサーバーでは、2025年に「許可ディレクトリ」の制限をすり抜けるCVEが2件出ています。残るのはOS側の境界です。
- サンドボックスで防げないものを知っておく。プロンプトインジェクションは止まらず、渡した認証情報の使い道も制限できません。そこはスコープ、Egress許可リスト、ログで補います。
目次
- MCPサーバーのサンドボックス化とは
- なぜMCPサーバーにサンドボックスが必要か(脅威モデル)
- MCP仕様 2026-07-28版の要求事項
- サンドボックスがあれば被害を抑えられた4つのCVE
- 隔離レイヤーの比較:プロセスサンドボックス・コンテナ・gVisor・microVM
- どのサーバーにどのレイヤーを使うか
- 検証:ローカルMCPサーバーを
srtで囲ってみた - コンテナでの隔離(DockerとgVisor)
- リモートMCPサーバーの隔離
- サンドボックスでは防げないもの
- MCPサーバー隔離チェックリスト(15項目)
- よくある失敗(症状→原因→対処)
- NodeFlareならこう解決できる
- FAQ
1. MCPサーバーのサンドボックス化とは
MCPサーバーのサンドボックス化とは、MCPサーバーをOSや仮想化の境界の中で動かし、読み書きできるファイル、接続できるホスト、使えるリソースを、サーバー自身のコードが何をしようとしても外側から制限することです。
ポイントは「外側から」という点です。多くのMCPサーバーは自分で制限をかけています。たとえば公式のファイルシステムサーバーは、アクセスしてよいディレクトリの一覧を受け取ります。しかしそれはアプリケーション側のルールで、攻撃者が突くのと同じコードが守っています。サンドボックスは、カーネル、ユーザー空間カーネル、ハイパーバイザーといったプロセスの外側が強制します。
この記事での用語は次のとおりです。
| 用語 | この記事での意味 |
|---|---|
| ローカルMCPサーバー | MCPクライアントが手元のマシンで起動するサーバー。多くはstdioトランスポート(クライアント設定の command と args) |
| リモートMCPサーバー | HTTP(Streamable HTTP)で接続するサーバー。自社または事業者の基盤で動く |
| 隔離境界 | プロセスの外側から制限をかける仕組み。Seatbelt / bubblewrapのサンドボックス、コンテナ、gVisor、仮想マシンなど |
2. なぜMCPサーバーにサンドボックスが必要か(脅威モデル)
MCPサーバーには、自分が書いていないコード、意図せず与えてしまう権限、そして信頼できない入力に誘導されうるLLMが選ぶ引数、という3つが1つのプロセスにそろいます。だから外側の壁が必要になります。
MCP仕様は、適切なサンドボックスと同意の仕組みがない場合のローカルサーバーへの攻撃経路として、次の3つを挙げています。
- クライアント設定に悪意のある起動コマンドを仕込む
- サーバー本体に悪意のあるペイロードを入れて配布する
- localhostで動いたままの安全でないローカルサーバーに、DNSリバインディングでアクセスする
隔離の有無で、何に届くかがどう変わるかを整理します。
| 脅威 | 隔離なし | ファイル+ネットワークを隔離 |
|---|---|---|
| 悪意のあるパッケージやインストールスクリプト | ~/.ssh、ブラウザのプロファイル、クラウドの認証情報を読み、どこへでも送れる |
許可したパスしか見えず、許可したホストにしか接続できない |
| サーバー自身のパスチェックのバグ | 「許可ディレクトリ」を抜けて、ユーザーが読めるすべてのファイルへ | 抜けた先もサンドボックスから見える範囲だけ。秘密情報は見えない |
プロンプトインジェクションによるツール呼び出し(write_file、run_command など) |
あなたの全権限で実行される | 書き込み許可リストとネットワーク許可リストの範囲内に限られる |
| 公開されたローカルHTTPポート(DNSリバインディング) | 閲覧したWebページからサーバーを操作されうる | 隔離だけでは解決しない。認証かstdioが必要(3章) |
| リソースの悪用(マイニング、フォーク爆弾) | CPUとメモリを使い切る | cgroupやVMの上限で止まる |
この表からサンドボックスの限界も見えます。被害範囲は小さくできますが、リクエストが正当かどうかは判断しません。
3. MCP仕様 2026-07-28版の要求事項
MCP仕様のサンドボックスに関する記述は、主にMCPクライアントとプロキシ向けのSHOULDで、MUSTは同意(コンセント)に関する1点です。関連する要件を1つの表にまとめます。
| 要件 | 仕様の文言(2026-07-28版) | 対象 | 実装のしかた |
|---|---|---|---|
| ワンクリック導入前の同意 | ワンクリックでのローカルサーバー設定に対応するクライアントは、実行されるコマンドを「省略せずに」表示し、明示的な承認を得なければならない(MUST) | MCPクライアント | 自分で設定ファイルに貼り付けるときも command と args を全部読む |
| 権限についての警告 | 「MCPサーバーはクライアントと同じ権限で動く」と警告すべき(SHOULD) | MCPクライアント | 隔離するまでは、ローカルサーバーは自分と同じことができる前提で扱う |
| 既定でサンドボックス | MCPサーバーのコマンドを最小限の権限のサンドボックス環境で実行すべき | MCPクライアント | srt、コンテナ、VMでコマンドを包む(7〜8章) |
| リソースの制限 | ファイルシステム、ネットワーク、その他のシステムリソースへのアクセスを制限して起動すべき | MCPクライアント | 書き込み許可リスト、秘密情報の読み取り禁止、ネットワーク許可リスト、CPU・メモリ上限 |
| 明示的な権限付与 | 必要なときに特定ディレクトリやネットワークへのアクセスを明示的に付与できる仕組みを用意すべき | MCPクライアント | ディレクトリもホストも1つずつ足す。~ 丸ごとは渡さない |
| プラットフォームのサンドボックス技術 | コンテナ、chroot、アプリケーションサンドボックスなどを使い、最新に保つ | MCPクライアント | サンドボックスツールのリリースも依存関係として追う |
| ローカル用サーバーは呼び出し元を絞る | ローカル実行を想定するサーバーはstdioを使うか、HTTPなら認可トークンやUnixドメインソケットなどで制限すべき | MCPサーバー作者 | 認証なしのHTTPを 0.0.0.0 で待ち受けない |
| stdioサーバーを起動するプロキシ | 起動するプロセスをサンドボックスまたはコンテナに入れ、ファイルアクセスを制限し、stdioの利用をすべてログに残すべき | ゲートウェイ・プロキシの作者 | サーバーごとにコンテナを分け、起動を記録する |
仕様が決めていないことも2つあります。特定のサンドボックス技術は指定しておらず、サーバーの既定のネットワークポリシーも定めていません。どちらも自分で決める部分です。
4. サンドボックスがあれば被害を抑えられた4つのCVE
次の4件は、MCPサーバーとその周辺ツールで「アプリ側のチェックだけでは足りない」ことを示す代表例です。内容はアドバイザリに書かれている範囲に限ります。
| CVE | 対象 | 影響版/修正版 | 深刻度(アドバイザリ記載) | 何が起きたか | サンドボックスがあれば |
|---|---|---|---|---|---|
| CVE-2025-53110 | @modelcontextprotocol/server-filesystem |
2025.7.1で修正 | 情報源によりHighまたはCritical | パスの先頭が許可ディレクトリと一致すると、パス検証をすり抜けられた | すり抜けても届くのはOSのサンドボックスが見せる範囲だけ |
| CVE-2025-53109 | @modelcontextprotocol/server-filesystem |
2025.7.1で修正 | High | fs.realpath() 周辺のエラー処理が原因で、許可ディレクトリ内のシンボリックリンクから意図しないファイルに届いた |
同上。サンドボックス外を指すリンクは解決できない |
| CVE-2025-49596 | MCP Inspector | 0.14.1未満/0.14.1 | CVSS 4.0で9.4(Critical)、CWE-306 | 認証がなく、認証なしのリクエストからstdio経由でMCPコマンドを起動できた | プロキシが起動するコマンドが、あなたの権限ではなくサンドボックス内で動く |
| CVE-2025-6514 | mcp-remote |
0.0.5以上0.1.16未満/0.1.16 | CVSS 3.1で9.6(Critical) | 信頼できないMCPサーバーに接続した際、細工された authorization_endpoint でOSコマンドインジェクション |
注入されたコマンドもサンドボックスの制限を受ける |
4件に共通するのは次の点です。
- 脆弱だったチェックが唯一の防御だった。ファイルシステムサーバーの許可ディレクトリは良い機能ですが、バグ1つで無効になりました。外側の境界があれば
~/.sshには届きません。 - 開発ツールも対象になる。Inspectorや
mcp-remoteはMCPサーバーではありませんが、手元でサーバーを起動したり接続したりします。仕様の「stdio Transport Security in Proxy Scenarios」の推奨どおり、プロキシ層も隔離しましょう。 - まずはパッチ。サンドボックスは被害を減らすだけで、脆弱な版を安全にはしません。
ツール説明文の汚染やラグプル(サンドボックスでは検知できない攻撃)は、MCPのtool poisoning対策ガイドで解説しています。
5. 隔離レイヤーの比較:プロセスサンドボックス・コンテナ・gVisor・microVM
レイヤーの違いは、ホストと何を共有するかです。共有するもの(ファイル、ネットワークスタック、カーネル)が少ないほど、侵害されたときに届く範囲は狭くなり、そのぶん準備の手間は増えます。
| レイヤー | 例 | ホストと共有するもの | 防げること | 防げないこと | MCPでの使いどころ |
|---|---|---|---|---|---|
| クライアントの同意と設定レビュー | クライアントの導入ダイアログ、mcp.json のレビュー |
すべて | 明らかに怪しい起動コマンド | 巧妙なものやパッケージ内部の悪意 | 必須だが、それだけでは不十分 |
| OSのプロセスサンドボックス | Anthropic Sandbox Runtime(srt):macOSはSeatbelt、Linuxはbubblewrap |
カーネル、ファイルシステムの大部分(読み取り専用)、ユーザー | 許可外への書き込み、禁止パスの読み取り、許可外ホストへの接続 | カーネルの脆弱性、禁止し忘れたファイルの読み取り | 信頼しているが閉じ込めたいローカルサーバー |
| コンテナ(runc) | Docker、Docker MCP Toolkit | カーネル | ホストのファイル(マウントしない限り)、ホストのプロセス、CPU・メモリの上限 | カーネルの脆弱性、マウントや環境変数で渡したもの | サードパーティ製ローカルサーバー、多くのリモートサーバー |
| ユーザー空間カーネル付きコンテナ | gVisor(runsc) |
ごくわずか。gVisorは「システムコールをホストにそのまま渡さない」 | カーネルの攻撃面の大部分 | Spectreなどのサイドチャネル(gVisorのドキュメントより)。未実装のシステムコールは単に失敗する | マルチテナント基盤、信頼できないコード |
| microVM | Firecracker(KVM) | ハイパーバイザーとホストOS | ホストへのカーネルレベルの脱出(ホストが適切に設定されている前提) | ホストの設定ミス、VMに許可したネットワーク先 | 他人のMCPサーバーの実行、サーバー単位の大規模な隔離 |
表の根拠になっている一次情報は次のとおりです。
srtは「コンテナなしで、任意のプロセスにOSレベルでファイルシステムとネットワークの制限をかける」ツールです。読み取りは既定で全許可でdenyReadで絞り、書き込みは既定で全拒否でallowWriteで開け、ネットワークは既定で全拒否でnetwork.allowedDomainsで開けます。位置付けは「Beta Research Preview」です。- Docker MCP Toolkitは、各MCPサーバーを専用コンテナで動かし、CPU 1個・メモリ2GBに制限し、既定では「ホストのファイルシステムにアクセスできない」としています。
mcp/配下のイメージはDockerがビルド・署名し、SBOMが付きます。 - gVisorは「ユーザー空間で動くアプリケーションカーネル」として振る舞います。代わりに、gVisorが再実装していないカーネル機能はサンドボックス内のワークロードから使えません。
- FirecrackerはKVMでmicroVMを動かし、不要なデバイスや機能を省いた最小構成でメモリ使用量と攻撃面を減らしています。jailerはcgroup / namespaceの隔離をかけてから権限を落とします。ただし安全性は「適切に設定されたLinuxホスト」に依存します。
6. どのサーバーにどのレイヤーを使うか
判断の軸は2つです。誰が書いたコードか、誰のデータに届くか。
| 状況 | 最低限 | 追加を検討する条件 |
|---|---|---|
| 公式・有名なサーバーを、自分のマシンで、自分のデータに使う | 書き込み許可リスト、秘密情報の denyRead、ネットワーク許可リストを設定したプロセスサンドボックス |
URLを受け取る、コマンドを実行するサーバーならコンテナへ |
| レジストリで見つけた、まだレビューしていないコミュニティ製サーバー | ホストのマウントなし、読み取り専用ルートFS、非root、API以外のネットワークなしのコンテナ | 広いファイルアクセスが必要なら、ホームディレクトリではなくコピーを渡す |
| コードやシェルコマンドの実行が本来の機能のサーバー | gVisor付きコンテナ、またはmicroVM | ネットワーク許可リストとCPU・メモリ上限は常に付ける |
| 社内SaaSをチーム向けに公開するリモートサーバー | サーバーごとに1コンテナまたは1VM、実行時に注入する秘密情報、Egress許可リスト | マルチテナントで運用するならサーバーごとにmicroVM |
| 他社・他人のMCPサーバーを動かすプラットフォーム | サーバーごとのmicroVM(またはgVisor)、サーバーごとのEgressポリシー、認証情報を共有しない | — |
覚えておくと便利な目安は、サーバーが任意のコードを実行できるようになった時点(シェルツール、コードインタプリタ、ビルド処理など)で、レイヤーを1段上げることです。
7. 検証:ローカルMCPサーバーを srt で囲ってみた
調査用のスクリプトと公式のファイルシステムMCPサーバーをAnthropic Sandbox Runtimeで囲み、何が止まり何が止まらないかを確かめました。環境は srt 0.0.80、Ubuntu 24.04(Linux、bubblewrap)、Node.js 22、2026年10月19日です。以下ではパスを短くしています。
設定ファイル:
{
"network": {
"allowedDomains": ["registry.npmjs.org"],
"deniedDomains": []
},
"filesystem": {
"denyRead": ["/work/fakehome/.ssh"],
"allowWrite": ["/work/proj"],
"denyWrite": ["/work/proj/.env"]
}
}
任意のコマンド(MCPサーバーも同じ)をこの中で動かします。
npm install -g @anthropic-ai/sandbox-runtime
srt --settings ./srt-settings.json ./probe.sh
結果:
| 試したこと | srt なし |
srt あり |
|---|---|---|
denyRead のディレクトリにあるダミーのSSH鍵を読む |
中身が読めた | No such file or directory(ディレクトリごと見えない) |
allowWrite 内にファイルを書く |
成功 | 成功 |
proj/.env(denyWrite)を上書き |
成功 | Read-only file system |
allowWrite の外にファイルを書く |
成功 | Read-only file system |
許可した registry.npmjs.org へHTTPS |
200 | 200 |
許可していない pypi.org と github.com へHTTPS |
到達できた | 接続できない |
169.254.169.254(クラウドのメタデータ用アドレス)へHTTP |
検証環境のプロキシが応答 | 接続できない |
続いて、同じサンドボックスの中で公式のファイルシステムMCPサーバーを proj を許可ディレクトリとして起動し、stdio経由でツールを呼びました。
| ツール呼び出し | サンドボックスの設定 | 結果 |
|---|---|---|
proj/note.txt への write_file |
上と同じ | 書き込めた |
proj/.env の read_text_file |
上と同じ(.env は denyWrite のみ) |
中身が返ってきた |
proj/.env の read_text_file |
.env を denyRead に追加 |
EACCES: permission denied、isError: true |
わかったこと:
denyWriteが守るのは改ざんで、漏えいではない。srtは読み取りが既定で許可なので、許可ディレクトリの中の秘密情報はdenyReadに入れるまで読めます。~/.ssh、~/.aws、~/.config/gcloud、.env、ブラウザのプロファイルは明示的に禁止しましょう。- 禁止より「見えない」ほうが強い。Linuxでは
denyReadのディレクトリがサンドボックス内に存在しない扱いになり、ファイル名も漏れません。 - ネットワークは既定で拒否。応答したのは許可したホストだけでした。これで「秘密を読まれた」が「読まれたが外へは送れなかった」に変わります。
- 設定の不備は安全側に倒れる。最初の設定ファイルには
network.deniedDomainsがなく、srt0.0.80は既定値で動くのではなく起動を拒否しました。設定を自動生成するときは、この挙動を前提にしてください。
クライアント設定でローカルMCPサーバーを囲むには、srt のREADMEのとおり command を srt にし、元のコマンドを args に移します。
{
"mcpServers": {
"filesystem": {
"command": "srt",
"args": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects/demo"]
}
}
}
頼る前に知っておきたい制約が2つあります。srt はベータのリサーチプレビューで設定形式が変わる可能性があること、そしてLinuxではbubblewrap、socat、ripgrepが必要なこと(Ubuntu 24.04では非特権ユーザー名前空間の許可が要る場合もあります)。allowAppleEvents や enableWeakerNetworkIsolation などは隔離を弱めるオプションなので、理由がない限りオフのままにします。
8. コンテナでの隔離(DockerとgVisor)
サードパーティ製のMCPサーバーには、コンテナが現実的な標準です。マウントしない限りホストのファイルは見えず、CPUとメモリにも上限をかけられます。以下は標準的な docker run のオプションです。このコマンドそのものは検証環境では実行していないので、自分のイメージで調整・確認してから使ってください。
docker run -i --rm \
--read-only --tmpfs /tmp \
--cap-drop ALL --security-opt no-new-privileges \
--user 65532:65532 \
--memory 512m --cpus 1 --pids-limit 128 \
--network none \
-v "$PWD/data:/data:ro" \
example/mcp-server:1.4.2
| オプション | MCPサーバーにとっての意味 |
|---|---|
-i |
標準入力を開いたままにし、クライアントがstdioで話せるようにする |
--read-only --tmpfs /tmp |
自分のコードを書き換えたり、永続的なファイルを置いたりできない |
--cap-drop ALL、no-new-privileges |
Linuxのケーパビリティを外し、setuidバイナリ経由の権限昇格を防ぐ |
--user 65532:65532 |
コンテナ内でもrootにしない |
--memory、--cpus、--pids-limit |
暴走ループやフォーク爆弾を止める |
--network none |
ネットワークなし。必要なら、サーバーのAPIにだけ届くネットワークに差し替える |
-v ...:ro |
必要なデータだけを、できれば読み取り専用でマウント |
| タグやダイジェストの固定 | latest のままだと、知らないうちに中身が変わる |
認証情報は、そのサーバーに必要なAPIトークン1つだけを、ツール単位のスコープで絞って渡します。ホームディレクトリやDockerソケットはマウントしません。
Docker MCP Toolkit / Gatewayを使う場合は、これらの多くが既定で入っています。docker mcp gateway run のリファレンスには、--cpus(既定1)、--memory(既定2Gb)、--block-secrets(既定true。ツールとの間で秘密情報の送受信をブロック)、--block-network(禁止されたネットワーク資源へのアクセスをブロック)、--verify-signatures(サーバーイメージの署名を検証)、--log-calls(既定true)があります。sse や streaming トランスポートでは、DNSリバインディング対策として MCP_GATEWAY_AUTH_TOKEN によるlocalhost認証を使います。
gVisorを足す場合は、gVisorをインストールしてDockerのランタイムとして登録し、上のコマンドに --runtime=runsc を加えます。コンテナはホストのカーネルではなく、gVisorのユーザー空間カーネルと話すようになります。gVisorが実装していない機能は使えないため、先に動作確認をしてください。
9. リモートMCPサーバーの隔離
リモートMCPサーバーの隔離は、1台が侵害されたときに基盤やほかのサーバーを守るためのものです。次の5つでほとんどをカバーできます。
- 1つの隔離境界に1つのサーバー。同じコンテナに2つのMCPサーバーを入れると、ファイル、環境変数、ネットワーク上の身元を共有します。「URL取得」サーバーが侵害されたときにCRMサーバーのトークンまで渡らないよう、コンテナかVMを分けます。
- 秘密情報はビルド時ではなく実行時に注入する。ビルド引数に入れた秘密はイメージのレイヤーやビルドログに残ります。保存時は暗号化し、起動時に注入します。
- Egressはサーバーごとに絞る。サンドボックスのネットワーク制限が、持ち出し対策そのものです。まずログだけ取るモードで動かし、そのあと正確なホスト名で強制します。手順はMCPのSSRF対策とEgress制御ガイドで解説しています。
- 認証は境界の手前に置く。CVE-2025-49596は認証の欠如が原因でした。サンドボックスは到達された後の被害を抑えるもので、そもそも到達させるかどうかは認証とIP許可リストが決めます。
- サーバー内のコード実行も隔離する。ツールがLLMの書いたコードを実行するなら、そのコードには、ファイルシステムも環境変数もなく、タイムアウトとメモリ上限のある短命のサンドボックスを別に用意します。
stdioサーバーを手元のPCから外へ移すなら、stdio MCPサーバーをリモートで動かす手順でHTTPブリッジを比較しています。ブリッジとサーバーは同じ境界の中に置いてください。
10. サンドボックスでは防げないもの
サンドボックスが制限するのは「どこに届くか」で、「その呼び出しが妥当か」は判断しません。次のものには別の対策が必要です。
| サンドボックスでは止まらないもの | 理由 | 効く対策 |
|---|---|---|
| プロンプトインジェクション、汚染されたツール説明 | 許可された範囲の中でLLMが誘導される | 書き込み・外部送信の前に人間が承認、ツール定義の固定 |
| サーバーが正当に持つ認証情報の悪用 | 注入したトークンはサンドボックス内でも有効 | トークンのツール単位スコープ、サーバーごとに1トークン |
| 許可したホストへの持ち出し | 許可は許可。書き込めるチケット管理やペーストサービスは出口になる | 許可リストを狭く保つ、ログで「読んでから送る」パターンを監視 |
| サーバーが読むべきデータ | 顧客テーブルを読めるなら、顧客テーブルを返せる | データアクセスの最小権限、結果のフィルタ |
| カーネル・ハイパーバイザーの脆弱性 | カーネル共有(プロセスサンドボックス、runc)やホスト側のバグ | レイヤーを上げる、ホストを最新に保つ |
| 認証なしのネットワーク公開 | サンドボックスは呼び出し元を認証しない | ローカルはstdio、HTTPはトークンとIP許可リスト |
11. MCPサーバー隔離チェックリスト(15項目)
ローカルMCPサーバー
- [ ] MCPクライアント設定の
commandとargsを、初回起動前にすべて読んだ - [ ] 各ローカルサーバーを、自分のユーザー権限のままではなくOSサンドボックスかコンテナで動かしている
- [ ] 書き込みは、サーバーが扱うディレクトリだけに許可している
- [ ]
~/.ssh、クラウドCLIの認証情報、ブラウザのプロファイル、.envを読み取り禁止にしている - [ ] ネットワークは既定で拒否し、ホスト単位で開けている
- [ ] ローカルサーバーはstdioを使い、ローカルのHTTP待ち受けにはトークンかUnixソケットを必須にしている
- [ ] サーバーを起動する開発ツール(Inspector、ブリッジ、プロキシ)も更新・隔離している
コンテナとリモートサーバー
- [ ] 1コンテナ(1VM)に1サーバー。環境変数やボリュームを共有していない
- [ ] 非rootユーザー、読み取り専用ルートFS、ケーパビリティ全削除、
no-new-privileges - [ ] CPU・メモリ・プロセス数の上限を設定している
- [ ] イメージをバージョンかダイジェストで固定し、可能なら署名や来歴を確認している
- [ ] 秘密情報は実行時に注入し、保存時に暗号化し、イメージやビルドログに含めていない
- [ ] サーバーごとのEgress許可リストを、ログのみの段階を経て強制している
- [ ] コードを実行するサーバーは、gVisor、microVM、またはリクエスト単位の入れ子サンドボックスで動かしている
- [ ] 認証とツール単位のスコープを、リクエストがサーバーに届く前に強制している
12. よくある失敗(症状→原因→対処)
| 症状 | 原因 | 対処 |
|---|---|---|
サンドボックス内のサーバーが .env の中身を返す |
denyWrite だけ設定。読み取りは既定で許可 |
秘密情報を denyRead に追加 |
| 手元では動くのに、サンドボックス内ではネットワークエラー | APIのホストが許可リストにない | 正確なホスト名を追加。広いワイルドカードは避ける |
| コンテナで隔離したはずが、ホームディレクトリを読める | -v ~:/home のような便利マウント |
プロジェクトのディレクトリだけを、できれば読み取り専用でマウント |
| サーバーがほかのコンテナを起動できる | Dockerソケットをマウントしている | /var/run/docker.sock は絶対にマウントしない |
| 1つのサーバーから漏れたトークンで別サービスまで被害 | 複数サーバーが同じコンテナと環境変数を共有 | 境界ごとに1サーバー、サーバーごとに1認証情報 |
| gVisorのコンテナが起動直後に落ちる | gVisorが実装していないシステムコールや機能が必要 | 先に runsc で動作確認。だめならmicroVMへ |
| 設定変更でルールが黙って消える | 自動生成した設定の項目漏れや不正値 | 設定を検証する。安全側に倒れるツールを選ぶ |
| 隔離したのに持ち出せてしまう | 許可リストに書き込み可能な公開サービスが入っている | 外すか、スコープを絞ったツール経由にする |
13. NodeFlareならこう解決できる
NodeFlareはリモートMCPサーバーのホスティングサービスで、各サーバーは専用のFirecracker microVMの中で動き、すべてのリクエストをプロキシが認証・認可します。この記事のうち「リモートサーバーの隔離」の部分をまとめて引き受けられます。一方、手元のPCで動かすローカルのstdioサーバーの隔離(7章)は、引き続き利用者側の作業です。記事で挙げたリスクと、ドキュメントに記載された機能の対応は次のとおりです。
| この記事のリスク | NodeFlareの機能 | 詳細 |
|---|---|---|
| 侵害された1台がホストやほかのサーバーに届く(5章、9章) | サーバーごとのFirecracker microVM | 各サーバーが専用のFirecracker microVMで動く |
| 秘密情報がイメージやログに残る(9章の2) | 暗号化されたシークレットと起動時注入 | 環境変数は保存時に暗号化され、VM起動時にだけ注入される。ビルド引数、イメージのレイヤー、ログには出ない。ビルドログは既知のトークン形式をマスク |
| 侵害されたサーバーからの持ち出し(9章、10章) | Egress制御 | モードは off(既定)、observe(ブロックせず接続先を記録)、enforce(リスト外をブロック)。最大100件(正確なホスト名、先頭1つのワイルドカード例 *.openai.com、IP)。ホスト側でDNSとnftablesにより強制し、通信内容は復号しない |
| CVE-2025-49596のような認証なしのアクセス(4章) | プロキシでの認証 | mcp_* 形式のAPIキーはハッシュで保存、またはOAuthアクセストークンをプロキシが検証。同じIPから誤ったキーが続くと、そのIPを10分間ロック。サーバーは既定で非公開 |
| サンドボックス内で使える認証情報が広すぎる(10章) | ツール単位のスコープ | tools:call:<ツール名>、resources:read:<uri>、prompts:get:<name> などを転送前にチェック。拒否されたリクエストはJSON-RPCエラーになり、サーバーには届かない |
| 想定外のネットワークからのアクセス(9章の4) | IP許可リスト(ネットワークアクセス制限) | ポリシーを restricted にしてIPv4/IPv6アドレスまたはCIDRを登録。認証より前、VM起動より前に判定し、リストが空ならすべて拒否。ネットワークアクセス制限はPro・Teamプランで利用可能 |
| サーバー内でLLMが書いたコードを実行する(9章の5) | コードモードのサンドボックス | リクエストごとのDenoサブプロセスで、ファイルシステム・環境変数・プロセス起動なし。通信はコールバック先のみ。既定のタイムアウト600秒、ツール呼び出し上限50回、V8ヒープ上限128MB |
| 侵害されたサーバーが何をしたか分からない(10章) | リクエストログ | リクエストごとに mcp_method、tool_name、arg_keys(キー名のみ)、http_status、outcome(scope_denied など)、caller_kind、client_ip を記録。保存期間はFreeで7日、Pro・Teamで30日 |
NodeFlareでもできないこと:LLMの中で起きるプロンプトインジェクションやtool poisoningは止められません。Egress制御は自分でオンにするまで off です。手元で動かすサーバーは隔離しません。狭いスコープ、Egress許可リスト、ログで、乗っ取られたエージェントの行動を制限し、可視化します。
最小の始め方:
- GitHubリポジトリからMCPサーバーをデプロイし、APIトークンは初回ビルド前にSettingsでシークレットとして登録します。デプロイ時には実際のMCP
initializeで動作確認されます。 - 呼び出し元ごとに
mcp_*キーを発行し、必要なtools:call:<ツール名>のスコープだけを付けます。 - Egress制御を1週間
observeで動かし、記録された接続先を許可してenforceに切り替えます。
1サーバーまでは無料で試せます:NodeFlareを始める
14. FAQ
MCPサーバーのサンドボックス化とは何ですか?
MCPサーバーをOS、コンテナ、仮想マシンの境界の中で動かし、使えるファイル、通信先、リソースを制限することです。制限はサーバーのコードの外側から強制されるので、サーバーに悪意やバグがあっても効きます。
ローカルのMCPサーバーもサンドボックスに入れるべきですか?
自分で書いていないものは入れるべきです。ローカルのMCPサーバーはMCPクライアントと同じ権限で動くため、あなたのユーザーが読めるものは何でも読めます。MCP仕様 2026-07-28版も、クライアントはサーバーのコマンドを最小限の権限のサンドボックスで実行すべき(SHOULD)としています。
MCP仕様ではサンドボックスは必須ですか?
必須ではなく推奨です。サンドボックス化、ファイルとネットワークの制限、明示的な権限付与は、クライアント向けのSHOULDです。stdioサーバーを起動するプロキシも隔離すべきとされています。MUSTは同意で、ワンクリック導入に対応するクライアントは、コマンド全体を表示して承認を得る必要があります。
DockerだけでMCPサーバーの隔離は十分ですか?
ホストのマウントなし、非rootユーザー、ケーパビリティ削除、リソース上限、ネットワーク制限をかけたDockerなら、サードパーティ製サーバーの標準としては十分です。ただしホストのカーネルを共有するので、信頼できないコードを実行するサーバーにはgVisorを足すかmicroVMを使ってください。
Claude Desktop、Claude Code、CursorでMCPサーバーをサンドボックスに入れるには?
サーバーの起動コマンドを包みます。command を srt や docker などのサンドボックスの起動コマンドにし、元のコマンドを args に移します。読める範囲、書ける範囲、接続先は、サンドボックス側の設定で決めます。
Anthropic Sandbox Runtime(srt)とは何ですか?
Anthropicが公開しているオープンソースのツールで、プロセスのファイルシステムとネットワークへのアクセスをOSレベルで制限します。macOSではSeatbelt、Linuxではbubblewrapを使います。書き込みとネットワークは既定で拒否、読み取りは既定で許可で、denyRead で絞ります。位置付けはベータのリサーチプレビューです。
MCPサーバーにはgVisorとFirecrackerのどちらが向いていますか?
どちらも通常のコンテナよりはるかに強く隔離します。gVisorはサーバーとホストの間にユーザー空間カーネルを挟む、コンテナのランタイムです。Firecrackerはサーバーごとに軽量なKVM仮想マシンを用意します。既存のコンテナを手軽に強化するならgVisor、信頼できない多数のサーバーを並べて動かすならmicroVMが向いています。
サンドボックスでプロンプトインジェクションやtool poisoningは防げますか?
防げません。サンドボックスが制限するのは、乗っ取られたサーバーやツール呼び出しが届く範囲です。許可された範囲の中でLLMが誘導されることは止められません。危険な操作の人間による承認、ツール単位のスコープ、ツール定義の固定、狭いEgress許可リストと組み合わせてください。
ローカルのMCPサーバーに絶対に読ませてはいけないものは?
最低限、~/.ssh、~/.aws や ~/.config/gcloud などのクラウドCLIの認証情報、ブラウザのプロファイル、パスワードマネージャーのデータ、.env です。今回の srt の検証では、.env は denyRead に入れるまで読めました。
リモートMCPサーバーはどう隔離すればよいですか?
1コンテナ(1VM)に1サーバーを置き、秘密情報は実行時に注入し、サーバーごとのEgress許可リストを強制し、手前に認証とツール単位のスコープを置きます。コードを実行するサーバーなら、そのコードにはタイムアウトとメモリ上限のある入れ子のサンドボックスを用意します。
サンドボックスに入れていれば、MCPサーバーのCVEは気にしなくてよいですか?
いいえ、まずパッチを当ててください。サンドボックスは悪用されたサーバーが届く範囲を狭めますが、許可された範囲の中にあるもの、つまりそのサーバー自身の認証情報やデータは悪用されえます。
まとめ
MCPサーバーのサンドボックス化は、本来あなたの全権限で動いてしまうコードの外側に壁を立てることです。MCP仕様 2026-07-28版は、クライアントがローカルサーバーを最小限の権限で、ファイルとネットワークを制限して動かすよう求めています。2025年のファイルシステムサーバーや周辺ツールのCVEは、サーバー自身のチェックがその壁にならないことを示しました。信頼度に応じて、信頼できるローカルサーバーには srt などのプロセスサンドボックス、サードパーティ製には堅めの設定のコンテナ、コード実行やマルチテナントにはgVisorかmicroVMを選びます。ファイルとネットワークはセットで制限し、秘密情報の読み取りは明示的に禁止し、リモートサーバーにはサーバーごとの境界、実行時注入の秘密情報、Egress許可リストを用意します。そのうえで、サンドボックスにはできない認証、ツール単位のスコープ、人間の承認、ログを重ねてください。脅威の全体像は、MCPのtool poisoning対策ガイドとMCPのSSRF対策とEgress制御ガイドもあわせてどうぞ。
参考資料(一次情報)
- MCP Specification 2026-07-28: Security Best Practices(Local MCP Server Compromise、stdio Transport Security in Proxy Scenarios)
- Anthropic Sandbox Runtime(srt)README
- Anthropic Engineering: Making Claude Code more secure and autonomous(サンドボックス)
- Docker MCP Toolkit ドキュメント
- docker mcp gateway run リファレンス
- gVisor: Introduction to gVisor security
- Firecracker README
- NVD: CVE-2025-49596(MCP Inspector)
- GitLab Advisory: CVE-2025-6514(mcp-remote)
- GitLab Advisory: CVE-2025-53110(server-filesystem)
- Wiz: CVE-2025-53109(server-filesystem)
- NodeFlare Docs
