flawopen.com/AI Security/mcp-python-sdk-oauth-issuer-confusion
MCP Python SDK OAuth issuer 验证缺陷
GHSA-qx49-fqc8-xw99 允许 HTTP MCP 服务器影响受影响的 Python SDK OAuth 客户端可能发送凭据的目标。请升级到 mcp 1.30.0 或 2.2.0;机器间认证提供方必须设置 issuer=。该问题没有 CVE 编号。[1], [3], [8]
公司把密封钥匙寄给经过批准的目录卡片上所列地址对应的银行。MCP 服务器可以提供这张卡片,而某条回退路径没有检查目录项是否确属预期银行。发行者验证会在寄出钥匙前,将卡片上的身份与配置中信任的银行进行比对。[1], [2]
核心概念与专有名词
MCP 客户端- 使用 Model Context Protocol 连接 MCP 服务器所提供工具或数据的应用。本问题影响将 Python SDK 用作 HTTP 客户端并使用其 OAuth 提供方的场景。[1]
框架映射
攻击执行流程分解
HTTP MCP 客户端持有 OAuth 凭据
应用使用受影响的 mcp 版本和 SDK 的某个 OAuth 提供方。它可能连接不完全可信的 MCP 服务器,同时持有客户端密钥、签名密钥或已存储的客户端注册信息。[1]
影响取决于提供方和授权范围
接收方可能在已授予范围内使用暴露的凭据或令牌。公告对无人值守提供方评为 CVSS 7.5;交互式提供方为 6.5,因为需要有人启动登录。公告称尚未分配 CVE。[1]
MCP Python SDK OAuth 版本与处置矩阵
| 客户端配置 | 公告记录的受影响条件 | 所需操作 |
|---|---|---|
使用 mcp 1.9.1–1.29.1 的 HTTP OAuth 客户端 | 所有发现路径都缺少 issuer 验证,且未始终将凭据绑定到对应 issuer。 | 升级到 mcp 1.30.0 或更高版本,并核实实际部署版本。 |
使用 mcp 2.0.0–2.1.1 的 HTTP OAuth 客户端 | 缺少 PRM 并进入旧版回退路径时受影响;403 insufficient_scope 后进行升级发现时也受影响。 公告中的软件包范围从预发布版本 2.0.0a1 开始,且为 <2.2.0;因此,受影响的 2.0.0 预发布版本也在范围内。 | 升级到 mcp 2.2.0 或更高版本,并核实实际部署版本。 |
使用预置凭据的 ClientCredentialsOAuthProvider 或 PrivateKeyJWTOAuthProvider | 受影响版本缺少 issuer=,无法将这些凭据绑定到预期授权服务器。 | 升级后显式设置 issuer=。从 1.x 中已弃用的 RFC7523OAuthClientProvider 迁移。 |
| SDK 构建的服务器、stdio 客户端或自行提供令牌/标头的客户端 | 该公告指出这些配置不受影响。 | 此特定问题无需处置;若应用还使用受影响的 HTTP OAuth 客户端,则需重新评估。 |
根本原因剖析 (Root Cause)
信任边界问题包含两个相互关联的部分:受影响的部分发现路径未始终将授权服务器元数据中的 issuer 与独立于 MCP 服务器所预期的发行者进行比较;已存储或预先配置的凭据也未绑定到其预期发行者。因此,恶意或已被入侵的 MCP 服务器可以将令牌交换引向其控制的端点,并接收客户端持有的 OAuth 材料。修复会在发现前确定预期发行者、拒绝不匹配的元数据,并将已存储的注册信息绑定到该发行者;无人值守的机器对机器提供方还必须显式设置 issuer=。[1], [2]
源代码对比:漏洞与安全实现
修复版本的 SDK 提供 issuer 参数,用于将机器间凭据绑定到所属授权服务器。它不能替代升级、清理旧的未绑定注册信息,或轮换可能已泄露的凭据。[2], [3], [8]
源码摘录: mcp.client.auth
import os
from mcp.client.auth import ClientCredentialsOAuthProvider
auth = ClientCredentialsOAuthProvider(
client_id=os.environ["MCP_CLIENT_ID"],
client_secret=os.environ["MCP_CLIENT_SECRET"],
)
import os
from mcp.client.auth import ClientCredentialsOAuthProvider
auth = ClientCredentialsOAuthProvider(
client_id=os.environ["MCP_CLIENT_ID"],
client_secret=os.environ["MCP_CLIENT_SECRET"],
issuer=os.environ["MCP_AUTH_ISSUER"],
)
# 请使用 mcp >= 1.30.0 (1.x) 或 >= 2.2.0 (2.x)。
工程与系统安全加固清单
- ✓盘点 HTTP MCP 客户端,并解析实际安装的
mcp版本,包括传递依赖和容器镜像。[1] - ✓将 1.x 客户端升级到
mcp1.30.0 或更高版本,将 2.x 客户端升级到 2.2.0 或更高版本;核验锁定文件和已部署环境。[1], [3], [8] - ✓为
ClientCredentialsOAuthProvider和PrivateKeyJWTOAuthProvider显式设置issuer=;迁移已弃用且不支持该选项的 1.xRFC7523OAuthClientProvider。[1], [2] - ✓清除发行者绑定功能加入前保存的 OAuth 注册信息,然后重新注册。自行预置的注册记录必须显式设置发行者。[1], [2]
- ✓FlawOpen 实施建议:将不可信 MCP 服务器视为可能接收凭据的信任边界。未经策略明确许可,不要将其连接到持有生产 OAuth 密钥或签名密钥的客户端。[1]
- ✓如果受影响客户端可能连接过不可信服务器,请轮换客户端密钥并在授权服务器撤销令牌。[1]
- ✓为 1.x 和 2.x 发现路径、issuer 不匹配、缺少 PRM、
403 insufficient_scope、绑定 issuer 的注册信息以及未设置issuer=的机器间提供方添加回归测试。[2] - ✓在判定其他客户端受影响前,请核对该公告的范围:SDK 构建的服务器、stdio 客户端以及自行提供令牌或标头的客户端均不受影响。[1]
参考来源
- GitHub-reviewed advisory GHSA-qx49-fqc8-xw99
- MCP Python SDK pull request #3398: Validate issuer on every discovery path
- MCP Python SDK v1.30.0 release notes
- MITRE CWE-345: Insufficient Verification of Data Authenticity
- The Hacker News: Official MCP Python SDK flaw can let malicious servers steal OAuth credentials
- Cycode disclosure: MCP Python SDK OAuth flaw
- CWE-522: Insufficiently Protected Credentials
- MCP Python SDK v2.2.0 release