作者在构建MCP红队工具时发现官方SDK的StreamableHTTPServerTransport在第二请求必返回500错误,已确认为真实协议层面Bug。
Model Context Protocol 正在经历艰难的一年。过去十四个月里:Anthropic 自家的 MCP Inspector 存在一个 CVSS 9.4 评分的 RCE 漏洞,GitHub 的 MCP 服务器存在一个 Prompt 注入泄露漏洞,2026 年 4 月发生了一次波及四种语言官方 SDK 的供应链披露事件——以及就在今年 6 月——RufRoot:某开源 Agent 平台(GitHub 星标 67,000+)中的一个未授权 MCP bridge,可通过单个 HTTP 请求实现完整远程代码执行。
现有的红队工具(garak、PyRIT、promptfoo)都是针对模型的 Prompt 注入和越狱攻击设计的。它们中没有任何一个会连接到一个活的 MCP 服务器并测试上述协议层面的故障模式——那些与模型说什么无关、只与服务器实际允许发生什么有关的模式。
所以我构建了 mcp-redteam:一个连接真实 MCP 服务器的小工具——通过 stdio 或 Streamable HTTP 方式——并运行六个对抗场景,每个场景都基于真实披露的事件或某个已获资助组织项目中的当前待处理问题。不是假设场景。
构建 HTTP 测试夹具时,我遇到了一个奇怪的现象:对无状态的 StreamableHTTPServerTransport 实例的第二次请求总是失败,返回一个赤裸裸的 500 状态码和空响应体——没有异常、没有堆栈跟踪、没有任何东西进入我的错误处理器。第一次请求(一个 initialize 调用)总是成功的。此后的每个请求,在同一个 transport 实例上,都不行。
我通过两种独立方式复现了这个问题——原始的 node:http 和 Express——然后才发现 modelcontextprotocol/typescript-sdk#1994:一个已确认的、仍未关闭的回归问题。1.25.0 的重写通过 @hono/node-server 的 getRequestListener 桥接 Node 的 HTTP 对象,而在这个桥接内部抛出的异常会变成一个通用的 Hono 500 错误——完全绕过了 SDK 自己的 onerror 回调和 JSON-RPC 错误格式化机制。这是一个真实的陷阱:SDK 自己的"无状态模式"示例并没有在请求之间重用 transport,但没有什么能阻止你这样做,而当你这样做时,失败从外部几乎无法诊断。
我在那个 issue 上发布了一个独立确认——在当前发布的 SDK 版本上复现,确认它不是特定于某个 HTTP 框架——修复方案(每个请求构造一个新的 transport)现在已经被写入 mcp-redteam 自己的测试夹具中,并附有解释其原因。
六个场景,每个都有真实引用,不是凭感觉:
Tool description/schema 稳定性——一个工具在被检查一次后是否改变了它的行为("rug pull")
未标注的破坏性工具——听起来具有破坏性但没有 destructiveHint 注解的工具
超大 payload 处理(可选)——一个"只读"工具是否对大参数进行了限制或挂起——呼应某真实 litellm PR 上的一个仍待处理的发现
未授权工具暴露——直接基于 RufRoot(CVE-2026-59726,CVSS 10.0)
Token audience 验证——服务器是否实际执行了 MCP 规范自己的 MUST-validate-audience 要求,还是只检查某个 Authorization header 是否存在
tools/call 授权绕过——tools/call 的 Gate 是否与 tools/list 一样严格,基于在 wso2/api-platform#2869 和两个独立的 litellm issues(#31977、#36358)中独立出现的相同模式
我不想只针对自己的夹具来发布这个工具,所以我在 LangFlow(153K+ GitHub stars)上运行了它——一个平台,有一个真实的、当前相关的 CVE(CVE-2026-33017,通过其 MCP adapter 的未授权 RCE,仍在广泛认为已修补的版本中可利用,per JFrog 的研究)。结果是干净利落的否定:LangFlow 实际的 MCP 协议端点在每个场景下都正确地要求了身份验证。值得直说——这不是一次漏报,这是工具在说实话。真正的 CVE 生活在不同层(LangFlow 自己的 REST API session-bootstrap 逻辑,不是其 MCP 服务器的协议处理),这超出了像这样一个纯 MCP 协议测试器的检查范围——我宁愿清楚地说出来,也不愿为了故事更精彩而强行给出阳性结果。
Prompt 注入工具已经是一条拥挤、资金充足的赛道(OpenAI 在 2026 年 3 月为这个确切领域收购了 Promptfoo)。协议层面的 MCP 测试——服务器是否实际执行了其自身规范的要求——则不是。上面每个场景都追溯到某个真实的、已获资助的组织正在处理的事情,不是我编造出来用来做东西的假设。
Repo: https://github.com/AAH20/mcp-redteam — 18/18 测试通过,CI 在 Node 20/22/24 上全绿,Apache-2.0 许可证。