Skip to main content
Glama
ibrahimsaleem

MCP Security Lab

MCP Security Lab

意図的に仕込まれた7つの脆弱性とその修正を含む、小さくて実際に動作するModel Context Protocolのセットアップです。単に読むだけでなく、各リスクが実際にどう機能するかを確認できます。現在の公式MCP仕様(2026-07-28)とそのセキュリティベストプラクティス文書、さらにOWASP MCP Top 10に基づいて構築されています。

すべてローカルで動作します。ここで扱うものは、実際に気にかけているシステムとは一切通信しません。

ドキュメント

以下の内容はすべてGitHub上で直接読むことができます(サーバーは不要です)。各ドキュメントは次のドキュメントへリンクしています:

  • docs/owasp-mcp-top10.md — OWASP MCP Top 10の全10リスクカテゴリのフィールドリファレンス、MCPサーバーが実際に何であるか、エンドツーエンドのリクエストパスとその3つの名前付きリスクゾーン、そして各カテゴリからそれを実証するエクスプロイトスクリプト(または最も近いもの)へのリンク。

  • docs/mcp-stateless-rewrite.md — 2026-07-28仕様のステートレス書き換えの前後アーキテクチャ図、それによって現在より重要になっているOWASPカテゴリの優先順位付きリスト、仕様/ロードマップの各変更を特定のOWASPカテゴリにマッピングする表、そして具体的な障害シナリオを伴う5つの新しい脆弱性パターン。

同じ2ページは、ダッシュボード内にライブのインタラクティブHTMLとしても存在します(guidelines.html と rewrite.html、下記のダッシュボードを参照)— 内容は同一で、ダッシュボード版はソースファイルではなくライブのエクスプロイトランナーに直接リンクしています。

Related MCP server: Damn Vulnerable Model Context Protocol (DVMCP)

対象範囲

ファイルツール

脆弱性

出典

run_diagnostics

コマンドインジェクション

OWASP MCP05

search_docs / get_secret_config

ツール(説明)ポイズニング

OWASP MCP03

get_cart

状態ハンドル乗っ取り

MCPセキュリティベストプラクティス

proxy_fetch_data

トークンパススルー / 混乱した代理人

MCPセキュリティベストプラクティス

read_user_file

不十分な認証 + 監査証跡なし

OWASP MCP07 / MCP08

read_calendar_events

スコープ拡大による権限昇格

OWASP MCP02

launch_from_config

クライアント起動インジェクション(サプライチェーンRCE)

OWASP MCP04 · 2026年の研究

servers/vulnerable_server.py には7つすべてが意図的に壊れた状態で含まれています。 servers/fixed_server.py には同じ7つのツールが修正済みで含まれています — 同じエクスプロイトを両方に対して実行して、結果が反転するのを確認してください。

OWASP MCP Top 10のすべてのカテゴリは、ダッシュボードのガイドラインページからデモ(または最も近い実際のもの)にリンクしています — ガバナンスのギャップであり単一ツール呼び出しのバグではないMCP09(シャドウMCPサーバー)も含み、専用のエクスプロイトスクリプトではなくラボ自体によって示されています。

最新情報の追跡

MCPは急速に進化しています — 2026-07-28の仕様リリースはプロトコル史上最大の書き換えでした(完全にステートレスになりました)。そして次のリリースをカバーする新しいロードマップが、つい数日前の2026-08-22に公開されました。このラボが構築されてから何が変わったか、そしてそれがリスクの状況をどう変えるかを追跡する場所が2つあります:

  • docs/owasp-mcp-top10.md — 「変更点」セクション、またはライブ版 http://127.0.0.1:8000/guidelines.html#2026-updates。

  • docs/mcp-stateless-rewrite.md — 完全な内訳。どのOWASPカテゴリが現在より重要になっているか、そしてその理由を含む。またはライブ版 http://127.0.0.1:8000/rewrite.html。

セットアップ

python -m venv .venv
source .venv/bin/activate         # Windows: .venv\Scripts\activate
pip install -r requirements.txt

mcp SDK v1.26.0で検証済み — サーバーは mcp.server.fastmcp から FastMCP をインポートします(一部のチュートリアルでは mcp.server から直接インポートするか、このSDKラインには存在しない mcp.server.mcpserver モジュールの MCPServer クラスを参照していますが、どちらも同じAPIです)。インストールされているバージョンが異なる場合は、pip show mcp を実行して dir(mcp.server) で正しいクラス名を確認してください — 他のすべて(.tool() デコレータ、.run(transport="stdio"))は変更されていません。

コマンドインジェクションのエクスプロイトは、マシンに実際の ping バイナリがなくても動作します — 重要なのはシェルのメタ文字(;)が実際に解釈されることを証明することであり、"PWNED" マーカーファイルがそれを確認します。

使用したいキーを環境変数として設定してください — 絶対に実際のキーを、コミットしたりチャットに貼り付けたりする可能性のあるファイルに入れないでください:

export OPENAI_API_KEY="sk-..."
# and/or
export GEMINI_API_KEY="AI..."

エクスプロイトの実行

7つのうち6つはLLMをまったく必要としません — MCPサーバーを直接呼び出して、欠陥がモデルの動作ではなくサーバーにあることを証明します:

# Command injection
python exploits/exploit_cmd_injection.py servers/vulnerable_server.py
python exploits/exploit_cmd_injection.py servers/fixed_server.py

# State handle hijacking (guessing another user's cart ID)
python exploits/exploit_state_hijack.py servers/vulnerable_server.py
python exploits/exploit_state_hijack.py servers/fixed_server.py

# Token passthrough / confused deputy
python exploits/exploit_token_passthrough.py servers/vulnerable_server.py
python exploits/exploit_token_passthrough.py servers/fixed_server.py

# Insufficient auth + no audit trail (reading another user's file by ID)
python exploits/exploit_auth_audit.py servers/vulnerable_server.py
python exploits/exploit_auth_audit.py servers/fixed_server.py

# Privilege escalation via scope creep (redirecting a read-only tool's token)
python exploits/exploit_scope_creep.py servers/vulnerable_server.py
python exploits/exploit_scope_creep.py servers/fixed_server.py

# Client launch injection / supply chain RCE (untrusted config picks command/args)
python exploits/exploit_launch_injection.py servers/vulnerable_server.py
python exploits/exploit_launch_injection.py servers/fixed_server.py

ツールポイズニングには実際のモデルが必要です。なぜなら、脆弱性はモデルがツール自身の説明に含まれる隠れた指示に従うかどうかだからです:

python exploits/exploit_tool_poisoning.py servers/vulnerable_server.py openai
python exploits/exploit_tool_poisoning.py servers/vulnerable_server.py gemini
python exploits/exploit_tool_poisoning.py servers/fixed_server.py openai

ダッシュボード

ローカルWebダッシュボードは、7つの脆弱性すべてをカードとして表示し、各脆弱性の脆弱版と修正版のコード差分を表示し、ボタンをクリックすると実際のエクスプロイトスクリプトをどちらかのサーバーに対して実行します — 出力はブラウザのライブターミナルパネルにストリーミングされ、VULNERABLE/SAFEの判定で終わります。

pip install -r requirements.txt -r ui/requirements.txt
uvicorn ui.server:app --reload --port 8000

次に http://127.0.0.1:8000 を開きます。ツールポイズニングカードを実行したい場合は、uvicornを起動するターミナルで OPENAI_API_KEY / GEMINI_API_KEY を設定してください — ダッシュボード自体はキーを要求することはなく、実行中のマシンにすでに設定されている環境変数を読み取るだけです。

自分で話しかけてみる

agent.py は汎用のMCPクライアント + エージェントループです — どちらかのサーバーとどちらかのプロバイダーを指定して、対話的にチャットできます:

python agent.py servers/vulnerable_server.py openai
python agent.py servers/fixed_server.py gemini

ドキュメントの検索、カートの確認、ホストの診断実行などを依頼してみて、[llm -> tool] / [tool -> llm] の行を見て、モデルが何を呼び出すと決定したか、何が返ってきたかを正確に確認してください。

ここで完全にカバーされていないもの

現在のMCPセキュリティ文書の2つの項目は実際に存在しますが、小さなローカルラボでデモするのは難しく、構築しなくても読む価値があります:

  • OAuthディスカバリによるSSRF — 悪意のあるサーバーがクライアントのメタデータ取得を 169.254.169.254(クラウドインスタンスメタデータ)に向けるもの。実際のOAuthフローと攻撃対象のネットワークが必要です。

  • Mix-up / localhostリダイレクトURIのなりすまし — 意味のあるデモには実際のマルチ認証サーバー設定が必要です。2026-07-28仕様はこれに対する具体的な緩和策を追加しました(クライアントは認証コードを交換する前に iss パラメータ(RFC 9207)を検証する必要があります)— ガイドラインページの「2026アップデート」セクションを参照してください。

両方とも詳細は https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/security_best_practices に記載されています。

拡張

  • 同じパターンに従って、別の脆弱なツールとそのエクスプロイトスクリプトを追加します:欠陥をコメントし、エクスプロイトを書き、修正を書きます。

  • インストールした実際のサードパーティMCPサーバーに対して同じエクスプロイトを実行してみてください(許可を得て、自分が所有するインフラ上で)— 状態乗っ取りと認証なしのパターンは、急いで構築されたサーバーで頻繁に発生します。

  • fixed_server.py の AUDIT_LOG を実際のログシンクに接続し、.denied イベントの小さな検出ルールを構築します — これは基本的にMCP08(監査/テレメトリ)を具体化したものです。

Related MCP Connectors

Related MCP Servers