FlawOpen

flawopen.com/AI Security/mcp-python-sdk-oauth-issuer-confusion

● CWE-345 / CWE-522 · CVSS 7.5[1] · 高危
安全研究 · FlawOpen

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]

CVSS 向量CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N[1]
💡 通俗易懂的原理解析 (ELI5)

公司把密封钥匙寄给经过批准的目录卡片上所列地址对应的银行。MCP 服务器可以提供这张卡片,而某条回退路径没有检查目录项是否确属预期银行。发行者验证会在寄出钥匙前,将卡片上的身份与配置中信任的银行进行比对。[1], [2]

核心概念与专有名词

MCP 客户端
使用 Model Context Protocol 连接 MCP 服务器所提供工具或数据的应用。本问题影响将 Python SDK 用作 HTTP 客户端并使用其 OAuth 提供方的场景。[1]
授权服务器发行者
签发令牌的 OAuth 服务的稳定标识。客户端必须将发现的元数据与独立预期的发行者进行比较。[1], [2]
Protected Resource Metadata (PRM)
可用于标识受保护资源授权服务器的元数据。缺少 PRM 时,SDK 还会使用旧版发现路径。[1], [2]
PKCE code verifier
客户端生成的秘密,用于将 OAuth 授权码交换绑定到发起流程的客户端。不得泄露给不可信端点。[1], [2]
CWE-345 / CWE-522
数据真实性验证不足:系统未充分确认数据来自预期来源便接受数据。 CWE-522 描述凭据保护不足。[1], [4], [7]

框架映射

攻击执行流程分解

步骤 1

HTTP MCP 客户端持有 OAuth 凭据

应用使用受影响的 mcp 版本和 SDK 的某个 OAuth 提供方。它可能连接不完全可信的 MCP 服务器,同时持有客户端密钥、签名密钥或已存储的客户端注册信息。[1]

步骤 2

服务器影响授权发现过程

mcp 1.9.1–1.29.1 在所有发现路径中都缺少 issuer 验证和凭据绑定。mcp 2.0.0–2.1.1 在缺少 PRM 并使用旧版回退路径时受影响,或在 403 insufficient_scope 后的升级发现中受影响。两个版本线的机器间提供方都没有 issuer= 来绑定预置凭据。 公告中的软件包范围从预发布版本 2.0.0a1 开始,且为 <2.2.0;因此,受影响的 2.0.0 预发布版本也在范围内。[1], [3], [8]

步骤 3

令牌端点收到凭据

客户端可能将客户端密钥、授权码和 PKCE 验证值,或签名断言,发送到这些元数据所选定的端点。具体凭据取决于提供方;并非所有客户端都会受影响。[1], [2]

步骤 4

影响取决于提供方和授权范围

接收方可能在已授予范围内使用暴露的凭据或令牌。公告对无人值守提供方评为 CVSS 7.5;交互式提供方为 6.5,因为需要有人启动登录。公告称尚未分配 CVE。[1]

步骤 5

固定发行者可弥合信任缺口

修复版本会在发现前确定预期发行者、拒绝不匹配的元数据,并将已存储注册信息绑定到该发行者。机器间认证提供方也必须显式设置 issuer=。[1], [2], [3], [8]

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)。

工程与系统安全加固清单

参考来源

← AI Security Directory →