Skip to main content
Glama
ibrahimsaleem

MCP Security Lab

MCP Security Lab

一个小巧、真实、可运行的 Model Context Protocol 配置,包含七个刻意设计的漏洞——以及它们的修复方案——让你亲眼看到每个风险的实际运作,而不只是阅读相关描述。基于当前官方 MCP 规范(2026-07-28)及其安全最佳实践文档,以及 OWASP MCP Top 10 构建。

一切都在本地运行。这里没有任何东西会与你关心的真实系统通信。

文档

以下所有内容都可以直接在 GitHub 上阅读——无需服务器——每份文档都链接到下一份:

  • docs/owasp-mcp-top10.md — 全部十个 OWASP MCP Top 10 风险类别的现场参考、MCP 服务器到底是什么、端到端请求路径及其三个命名风险区域,以及从每个类别直接链接到演示该类别(或最接近的)漏洞利用脚本的链接。

  • docs/mcp-stateless-rewrite.md — 2026-07-28 规范无状态重写的前后架构图、一份按优先级排序的列表,说明哪些 OWASP 类别因此变得更加关键、一张将每项规范/路线图变更映射到特定 OWASP 类别的表格,以及五个带有具体失败场景的新漏洞模式。

同样的两个页面也以实时、交互式 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 包含全部七个,故意弄坏的。 servers/fixed_server.py 包含同样的七个工具,已打补丁——对两者运行相同的漏洞利用脚本,观察结果翻转。

每个 OWASP MCP Top 10 类别现在都从仪表板的指南页面链接到一个演示(或最接近的真实演示)——包括 MCP09(影子 MCP 服务器),这是一个治理缺口而非单一工具调用 bug,因此由实验室本身而非专门的漏洞利用脚本来演示。

保持最新

MCP 发展很快——2026-07-28 规范发布是该协议迄今最大的一次重写(它完全变为无状态),而涵盖下一个版本的新路线图就在几天前(2026-08-22)刚刚发布。有两个地方追踪自本实验室构建以来发生了什么变化,以及这些变化如何改变风险图景:

  • 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 导入,或引用 mcp.server.mcpserver 模块中的 MCPServer 类,该模块在此 SDK 系列中不存在;无论哪种方式 API 相同)。如果你的安装版本不同,请运行 pip show mcp 并检查 dir(mcp.server) 以获取正确的类名——其他所有内容(.tool() 装饰器、.run(transport="stdio"))均未更改。

即使你的机器上没有真正的 ping 二进制文件,命令注入漏洞利用也能工作——关键在于证明 shell 元字符(;)确实会被解释,这一点由“PWNED”标记文件确认。

将你想要使用的密钥设置为环境变量——绝不将真实密钥放在你可能提交或粘贴到聊天中的文件中:

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

运行漏洞利用

七个中的六个完全不需要 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 安全文档中有两项是真实的,但在小型本地实验室中较难演示,即使你不构建它们也值得阅读:

  • 通过 OAuth 发现实现 SSRF — 恶意服务器将客户端的元数据获取指向 169.254.169.254(云实例元数据)。需要实际的 OAuth 流程和可攻击的网络。

  • 混合攻击 / 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