auditing-mcp-servers-for-tool-poisoning について
導入前の確認、インシデント対応、CI/CD で MCP サーバーを評価するセキュリティ監査スキルです。mcp-scan による検査と、説明文、SSRF、認証、ネットワーク公開の手動確認を組み合わせます。
主な機能
- 01MCP 設定のサーバーリスクをスキャン
- 02ツール、プロンプト、リソースの説明を確認
- 03ツールハッシュを固定して変更を検知
- 04URL 取得ツールの SSRF をテスト
- 05認証とネットワーク公開を確認
- 06ランタイムプロキシの防御を評価
活用シーン
- 01エージェント環境への追加前にサーバーを確認
- 02社内開発 MCP サーバーを監査
- 03承認済みツール説明の変更を検知
- 04CI/CD で MCP 設定の変更をスキャン
MCP 対応
MCP サーバーと公開されるツール、プロンプト、リソースを監査します。mcp-scan による静的・ランタイム分析と、手動のセキュリティ確認を行います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill auditing-mcp-servers-for-tool-poisoningインストール後、Claude Code で/auditing-mcp-servers-for-tool-poisoningを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdstandards.mdscripts/agent.py詳細
ツールポイズニングに対する MCP サーバーの監査
許可された用途に限る旨の注意: MCP サーバーを監査すると、稼働中のツールエンドポイントに接続し、プローブすることがあります。自分が所有するサーバー、または評価する権限を与えられたサーバーのみをスキャンしてください。スキャンしたツールの説明は信頼できない入力として扱ってください。監査を終えていない MCP サーバーを、特権を持つエージェントに読み込ませないでください。許可なく、SSRF や認証の脆弱性を調べる目的で第三者の MCP エンドポイントをプローブすると、違法となる場合があります。
概要
Model Context Protocol(MCP)を使うと、AI エージェントは MCP サーバーが公開する外部ツールを検出して呼び出せます。各ツールは名前と自然言語の説明を公開しており、エージェントの LLM はツールを呼び出すかどうかを決める前にこの説明を読みます。2025 年初頭、Invariant Labs は、この説明フィールドが攻撃対象領域となることを明らかにしました。悪意のあるサーバーはツールの説明に隠れた指示を埋め込むことができ(ツールポイズニング攻撃、OWASP MCP03:2025)、高性能なモデルはその指示に気付かれないまま従い、ファイルを持ち出したり、秘密情報を漏えいしたり、ツール呼び出しを転送したりしながら、ユーザーには通常どおりの応答を返します。ツールの説明はエージェントのコンテキストに読み込まれるため、ツールポイズニングは実質的に、サプライチェーンを通じて届けられる間接的なプロンプトインジェクションです(MITRE ATLAS AML.T0010 ML Supply Chain Compromise)。
ポイズニング以外にも、MCP サーバーには従来型のインフラストラクチャリスクがあります。悪意のあるサーバーが信頼されたツールの動作を上書きするツールのシャドーイング、ユーザーの承認後にツールの説明が変わるラグプル、データ流出を可能にするツールの組み合わせであるトキシックフロー、サーバー側で URL を取得するツールにおけるSSRF、ネットワークインターフェースにバインドされた MCP サーバーの認証されていない公開などです。このスキルでは、Invariant Labs のmcp-scanによる静的解析とランタイム解析に加え、SSRF と認証の手動チェック、ラグプルを検出するためのツールのピン留めを行い、MCP サーバーをエンドツーエンドで監査します。
使用する場面
- エージェントスタック(Claude Desktop、Cursor、VS Code、Windsurf、カスタムエージェント)に新しい MCP サーバーを追加する前。
- 内部で開発した MCP サーバーのセキュリティレビュー時。
- 承認済みのツールが気付かれないまま変更されていないことを検証する場合(ラグプル検出)。
- 変更のたびに MCP 設定と SKILL/ツール定義をスキャンする CI/CD ゲートとして。
- エージェントがポイズニングされたツールと一致する予期しない動作をした場合のインシデント対応時。
前提条件
- Python 3.10+ と
uv(uvx用)、または pip。 - スキャンする MCP 設定ファイル(例:
~/.cursor/mcp.json、~/.vscode/mcp.json、Claude Desktop の設定)。 - ツールをインストールします。
# uv provides uvx (recommended runner for mcp-scan)
curl -LsSf https://astral.sh/uv/install.sh | sh # or: pipx install uv
# mcp-scan (Invariant Labs) — no global install needed with uvx
uvx mcp-scan@latest --help
# For the runtime proxy mode (separate extra)
uvx --with "mcp-scan[proxy]" mcp-scan@latest proxy --help
# Manual probing helpers
pip install requests mcp
目標
- インストール済みのすべての MCP サーバーを静的にスキャンし、ツールポイズニング、シャドーイング、ラグプル、トキシックフローを検出します。
- ツール/プロンプト/リソースの説明をそのまま確認し、隠された指示や難読化された指示を調べます。
- ツールのハッシュをピン留めし、承認後に説明が変更されたことを検出します(ラグプル対策)。
- URL を取得するツールをテストし、サーバーサイドリクエストフォージェリ(SSRF)を確認します。
- MCP サーバーが認証されており、信頼できないインターフェースに公開されていないことを検証します。
- オプションとして、mcp-scan プロキシを使ってランタイムガードレールを適用します。
MITRE ATT&CK との対応
| ID | 正式名称 | 関連性 |
|---|---|---|
| AML.T0010 | ML Supply Chain Compromise | ポイズニングされたサードパーティ MCP サーバーは、エージェントのサプライチェーン侵害にあたります |
| AML.T0051.001 | LLM Prompt Injection: Indirect | ポイズニングされたツールの説明は、エージェントのコンテキストへの間接的なインジェクションです |
| AML.T0053 | LLM Plugin Compromise | MCP ツールはエージェントのプラグインであり、ポイズニングによって侵害されます |
| AML.T0057 | LLM Data Leakage | ポイズニングされたツールでよく使われるペイロード:ファイルや秘密情報の持ち出し |
ワークフロー
1. インストール済みの MCP 設定を静的にスキャンする
mcp-scan は既知の設定場所を自動検出します。パスを明示的に指定することもできます。
# Scan all auto-discovered MCP configs
uvx mcp-scan@latest
# Scan a specific config file
uvx mcp-scan@latest ~/.vscode/mcp.json
# Emit machine-readable JSON for CI
uvx mcp-scan@latest --json ~/.cursor/mcp.json > mcp_scan_report.json
mcp-scan は、ツールポイズニング、ツールのシャドーイング、オリジン間の権限昇格、ラグプル、トキシックフローにフラグを立てます。
2. 生のツール説明を調査する
検証を行わずに、すべてのツール/プロンプト/リソースの説明を出力し、隠れた指示、<important>形式のブロック、またはモデルに向けた命令文がないか読み取ります。
uvx mcp-scan@latest inspect ~/.cursor/mcp.json
注意すべき兆候を探します。アシスタントへの指示(「ユーザーに伝えないで」「~/.ssh/id_rsa を読んで」など)、偽のドキュメントを入れ子にしたもの、ゼロ幅文字や Unicode を使って偽装したテキスト、ほかのツールを呼び出す指示などです。
3. ツールのハッシュを固定してラグプルを検出する
mcp-scan はツールの説明のハッシュを追跡し、後から行われた変更が通知なしでも検出されます。定期的にスキャンを実行してください。以前に承認したツールのハッシュが一致しない場合、ラグプルが発生したことを示します。
# Re-run regularly; mcp-scan reports changed tool hashes since last approval
uvx mcp-scan@latest ~/.cursor/mcp.json
4. プログラムでツールを列挙し、メタデータを監査する
公式の MCP SDK でサーバーに接続し、公開されているスキーマを直接調査します。
# enumerate_tools.py (stdio MCP server example)
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
params = StdioServerParameters(command="node", args=["./suspect-mcp-server.js"])
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
for t in tools.tools:
print(f"{t.name}: {len(t.description or '')} chars")
print((t.description or "")[:400])
asyncio.run(main())
5. URL 取得ツールで SSRF をテストする
ツールが URL を受け取り、サーバー側で取得する場合は、内部のメタデータ/ループバック対象へのアクセスを試みます(自分が所有するシステムでのみ実施してください)。
# ssrf_probe.py
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
SSRF_TARGETS = [
"http://169.254.169.254/latest/meta-data/", # AWS IMDS
"http://127.0.0.1:22/", "http://localhost:6379/", "file:///etc/passwd",
]
async def main():
params = StdioServerParameters(command="node", args=["./suspect-mcp-server.js"])
async with stdio_client(params) as (r, w):
async with ClientSession(r, w) as s:
await s.initialize()
for url in SSRF_TARGETS:
res = await s.call_tool("fetch_url", {"url": url})
body = str(res.content)[:200]
print(f"[SSRF?] {url} -> {body}")
asyncio.run(main())
6. 認証とネットワークへの公開状態を確認する
リモート MCP サーバー(HTTP/SSE トランスポート)で認証が必要になっていること、および信頼できないネットワーク上で 0.0.0.0 にバインドされていないことを確認します。
# Confirm whether an SSE/HTTP MCP endpoint responds without credentials
curl -s -i http://mcp-host:8000/sse | head -n 20
# Check listening interfaces of a locally running MCP server
ss -tlnp | grep -E ':(8000|3000|6277)'
認証なしでツール一覧を返す、または tools/call を受け付ける MCP エンドポイントは、認証されていない公開状態です。トークン/OAuth を導入し、localhost または認証済みゲートウェイにバインドして是正してください。
7. 実行時のガードレールを適用する(任意)
継続的に保護するには、エージェントの MCP トラフィックを mcp-scan プロキシ経由にし、ツール呼び出し、データフロー制約、PII、間接的なインジェクションをリアルタイムでチェックします。
uvx --with "mcp-scan[proxy]" mcp-scan@latest proxy
8. 調査結果を報告する
各調査結果について、サーバー、ツール、証拠(汚染された説明/SSRF の応答/認証なしで取得できる一覧)、重大度、ATLAS へのマッピングを記録します。汚染されたサーバーの削除またはサンドボックス化、認証の追加、承認済みツールのハッシュ固定、プロキシの有効化を推奨します。
ツールとリソース
| ツール | 目的 | ソース |
|---|---|---|
| mcp-scan | 静的および実行時の MCP セキュリティスキャナー | https://github.com/invariantlabs-ai/mcp-scan |
| MCP Python SDK | プログラムによるツールの列挙/呼び出し | https://github.com/modelcontextprotocol/python-sdk |
| OWASP MCP Top 10 | MCP リスクのリファレンス(MCP03 ツールポイズニング) | https://owasp.org/www-project-mcp-top-10/ |
| Invariant Labs blog | ツールポイズニングの開示 | https://invariantlabs.ai/blog/introducing-mcp-scan |
| MITRE ATLAS | AI 脅威手法の分類体系 | https://atlas.mitre.org/ |
MCP 脅威リファレンス
| 脅威 | 説明 | 検出 |
|---|---|---|
| ツールポイズニング | ツールの説明に隠された指示 | mcp-scan によるスキャン/調査 |
| ツールシャドーイング | 悪意のあるサーバーが信頼済みツールを上書きする | mcp-scan のクロスオリジンチェック |
| ラグプル | 承認後に説明が変更される | mcp-scan のツール固定(ハッシュ) |
| 有害なフロー | 情報流出を可能にするツールの組み合わせ | mcp-scan の有害フロー分析 |
| SSRF | URL 取得ツールが内部の対象にアクセスする | 所有するサーバーに対する ssrf_probe |
| 認証なしの公開 | 認証のない MCP エンドポイント | curl/インターフェースと認証の確認 |
検証基準
- インストール済みの MCP 設定をすべて mcp-scan で静的スキャンした
- 生のツール/プロンプト/リソースの説明を調査し、隠れた指示がないか確認した
- ツールのハッシュを固定し、ラグプル検出を有効にした
- MCP SDK を使ってプログラムでツールを列挙した
- 所有する対象に対して URL 取得ツールの SSRF テストを実施した
- リモートサーバーの認証とネットワークへの公開状態を確認した
- 該当する場合、実行時プロキシのガードレールを評価または導入した
- 調査結果を MITRE ATLAS AML.T0010 と OWASP MCP03:2025 にマッピングした
- 各調査結果に重大度を割り当て、是正策を記録した
- 今後のラグプルを検出するため、再スキャンを予定した