MCP 身份验证与授权:OAuth 2.1、令牌委托和混淆代理问题

MCP Security OAuth 2.1 Authentication AI Security

身份验证是决定 MCP 服务器强大功能是提供给合法用户还是攻击者的守门员。如果做错了,其他所有安全控制都会变得无关紧要——一个未经身份验证或身份验证不良的 MCP 服务器如果能够访问电子邮件、文件和数据库,无论您如何加固其他所有内容,都是一个严重的漏洞。

OWASP GenAI 安全项目指南将身份验证和授权确定为 MCP 服务器八个核心安全域之一,其具体要求超出了大多数开发人员默认实现的内容。本文解释了这些要求存在的原因以及如何正确实现它们。

MCP 中的身份验证挑战

MCP 服务器面临比传统服务更复杂的身份验证环境,因为它们在多个主体之间进行调解:

  • 其指令驱动 AI 助手的用户
  • 解释指令并调用工具的 AI 模型
  • MCP 客户端(托管 AI 的应用程序)
  • 执行工具调用的 MCP 服务器
  • MCP 服务器代表用户调用的下游服务

这些关系中的每一个都需要自己的身份验证和授权控制。任何环节的弱点都可以被利用来绕过其他环节。

强制要求:远程服务器的 OAuth 2.1 和 OIDC

对于远程 MCP 服务器——那些通过网络而不是通过本地 STDIO 或 Unix 套接字访问的服务器——OWASP GenAI 指南是明确的:带有 OIDC 的 OAuth 2.1 是强制性的,而不是可选的。

此要求存在的原因是:

OAuth 2.1 提供显式范围控制。 每个访问令牌都准确声明它授权的资源和操作。MCP 服务器可以在工具调用时验证所提供的令牌是否具有该操作所需的特定范围——不仅仅是用户已通过身份验证,而且他们已被授权进行此特定操作。

OIDC 提供加密身份。 OpenID Connect 添加了 MCP 服务器可以验证的身份断言(ID 令牌),而无需往返到身份提供者。服务器在每个请求上验证 iss(颁发者)、aud(受众)、exp(到期时间)和签名。

OAuth 2.1 令牌在设计上是短期的。 现代 OAuth 规范(整合并取代了 OAuth 2.0 最佳实践)强调必须定期刷新的短期访问令牌。这限制了令牌被泄露时的损害窗口。

在每个请求上验证什么

不要仅在会话建立时验证令牌。在每次工具调用时进行验证:

def validate_token(token: str, required_scope: str) -> TokenClaims:
    claims = jwt.decode(
        token,
        key=get_public_key(claims_preview['kid']),
        algorithms=["RS256", "ES256"]
    )

    assert claims['iss'] == EXPECTED_ISSUER
    assert EXPECTED_AUDIENCE in claims['aud']
    assert claims['exp'] > time.time()
    assert required_scope in claims['scope'].split()

    return claims

永远不要跨请求缓存验证结果。在会话开始时有效的令牌可能在会话中途被撤销。

动态客户端环境

在 MCP 客户端频繁变化的环境中(例如,不同的 AI 助手连接到同一服务器),静态 API 密钥或预共享密钥是不够的。使用带有 OAuth 2.1 或 OIDC 的动态客户端注册在连接时验证客户端身份。允许列表、硬编码的连接策略或双向 TLS(mTLS)适用于特定客户端和服务器之间的已知静态关系。

Logo

准备好发展您的业务了吗?

今天开始免费试用,几天内即可看到结果。

混淆代理问题

理解攻击

混淆代理是一个经典的授权漏洞,在 MCP 架构中有特别危险的表现形式。该攻击利用了 MCP 服务器以谁的权限行事的模糊性。

考虑这个场景:

  • 用户 Alice 通过有限权限对 MCP 服务器进行身份验证——她可以读取自己的文件,但不能读取其他人的文件
  • MCP 服务器具有广泛的服务账户权限,可以读取组织中的所有文件
  • MCP 服务器使用令牌直通:它将 Alice 的令牌转发到下游服务

当 Alice 要求 AI 助手"总结我的项目文件夹"时,服务器使用 Alice 的令牌访问她的文件——正确的行为。但是,如果攻击者诱骗服务器使用其自己的服务凭据发出请求(可能通过工具投毒攻击或间接提示注入),则服务器的提升权限将用于访问 Alice 未被授权查看的文件。

服务器是"混淆的代理"——它被诱骗代表没有该权限的人使用其权限,充当特权提升的代理。

为什么令牌直通会产生此漏洞

许多 MCP 实现为了简单起见将客户端的令牌转发到下游 API。这似乎很直观——用户的令牌代表用户的权限,因此将其用于所有下游调用可以保持正确的访问控制。

问题是:将 MCP 服务器识别为受信任中介的下游 API 可能会使用服务器的身份级别而不是转发的用户令牌的级别来授予请求。如果 MCP 服务器出于自己的主动性行事——通过用户没有明确请求的 AI 决策——它可能会使用自己的凭据而不是用户的令牌。

转发用户令牌还会:

  • 破坏审计跟踪(下游日志显示用户身份,而不是服务器身份,从而模糊了 MCP 层)
  • 使入侵 MCP 服务器的攻击者能够访问所有转发的用户令牌
  • 如果不同用户的令牌可能被混淆或重放,则会产生合规性问题

解决方法:使用代表流的显式令牌委托

MCP 服务器应该使用 OAuth 的**代表流(On-Behalf-Of,OBO)**为下游服务访问获取自己的令牌,而不是转发客户端令牌:

用户向 MCP 客户端进行身份验证 → 客户端获取用户访问令牌
MCP 客户端向 MCP 服务器提供用户令牌
MCP 服务器通过 OBO 流将用户令牌交换为服务器令牌:
  POST /token
  grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
  assertion=<user_access_token>
  scope=<minimum_required_scope>
MCP 服务器使用自己的 OBO 令牌进行下游调用

OBO 令牌:

  • 明确限定为特定工具调用所需的最小权限
  • 将 MCP 服务器标识为调用方(用户作为主体)
  • 与用户的身份验证事件绑定(可以在用户会话结束时撤销)
  • 不会将用户的完整令牌暴露给下游服务

短期、限定范围的令牌

OWASP GenAI 指南提出了一个具体建议:颁发生命周期以分钟而不是小时来衡量的访问令牌。 这适用于 MCP 服务器从客户端接受的令牌和它为下游服务访问获取的令牌。

为什么短生命周期很重要

被盗的访问令牌在其整个生命周期内都是有效的,无论合法用户是否已注销、更改了密码或撤销了会话。在会话开始时被盗的 24 小时令牌为攻击者提供了 24 小时的持久访问。在会话中途被盗的 5 分钟令牌最多提供 5 分钟。

短期令牌还强制执行定期的重新身份验证事件,这提供了以下机会:

  • 重新检查用户的账户是否已被暂停或其权限已更改
  • 检测异常的身份验证模式(不寻常的时间、地点或频率)
  • 为敏感操作应用升级身份验证

令牌范围最小化

每个令牌应仅携带正在执行的特定操作所需的范围。当当前工具调用仅需要 read:files 时,不要颁发具有 read:files write:files delete:files 范围的令牌。这限制了令牌被拦截或模型被操纵进行意外工具调用时的损害。

def get_tool_token(user_id: str, tool_name: str) -> str:
    # 将工具映射到最小所需范围
    required_scopes = TOOL_SCOPE_MAP[tool_name]

    return oauth_client.get_token(
        subject=user_id,
        scopes=required_scopes,
        lifetime_seconds=300  # 5 分钟生命周期
    )

将会话视为状态,而非身份

一个常见的错误是将会话 ID 用作授权代理:如果请求携带有效的会话 ID,服务器就假定它已被授权。这混淆了状态管理和身份验证。

正确的模型:会话 ID 管理对话状态。授权通过验证 OAuth 令牌的声明在每个请求上独立验证。即使携带有效会话 ID 的请求也必须在允许任何工具调用之前提供有效、未过期、适当范围的 OAuth 令牌。

这很重要,因为会话 ID 可以被盗、猜测或以 OAuth 令牌(携带加密完整性保证)无法实现的方式重放。

集中式策略执行

OWASP GenAI 指南建议使用集中式策略网关,而不是在各个工具处理程序中实现分散的授权检查,该网关:

  • 在所有工具调用请求到达特定于工具的代码之前拦截它们
  • 验证身份验证(令牌签名、颁发者、受众、到期时间)
  • 执行授权(此特定工具所需的范围)
  • 应用同意验证(用户是否明确授权此类操作?)
  • 实施工具过滤(此工具在此部署上下文中是否允许?)
  • 使用完整上下文记录所有决策以进行审计

集中化确保策略在所有工具和代理中一致应用。特定于工具的授权检查可能在开发期间被遗忘或绕过;网关检查则不能。

总结:身份验证检查清单

对于远程 MCP 服务器,最低身份验证安全标准是:

  • 对所有连接强制执行 OAuth 2.1 / OIDC
  • 在每次工具调用时验证令牌签名、颁发者、受众和到期时间
  • 不向下游 API 进行令牌直通——使用 OBO 或服务器颁发的令牌
  • 访问令牌范围限定为每个工具所需的最小权限
  • 令牌生命周期以分钟为单位,强制刷新
  • 会话 ID 不用作授权代理
  • 设置集中式策略执行网关
  • 不可变地记录所有身份验证事件和授权决策

相关资源

常见问题

为什么 MCP 需要 OAuth 2.1 而不是更简单的身份验证方法?

远程 MCP 服务器需要 OAuth 2.1,因为它提供了具有显式范围控制、短期令牌、加密验证和标准化身份断言(通过 OIDC)的委托授权。像 API 密钥或会话 cookie 这样的简单方法缺乏实现最小权限访问所需的范围粒度,不提供加密身份保证,并且在会话结束时难以精细撤销。

MCP 中的混淆代理问题是什么?

混淆代理是一种特权提升攻击,其中 MCP 服务器被诱骗使用其自身的(更高的)特权来执行请求用户未被授权执行的操作。当使用令牌直通时会发生这种情况——服务器将用户的令牌转发到下游 API,这可能会基于服务器的受信任状态授予用户不应该拥有的访问权限。解决方法是使用代表流(On-Behalf-Of)令牌流,其中令牌明确为 MCP 服务器的特定访问范围颁发。

什么是令牌直通,为什么它在 MCP 中很危险?

令牌直通意味着 MCP 服务器将客户端的身份验证令牌直接转发到下游 API,而不是使用自己的服务器颁发的凭据。这很危险,因为:(1)它破坏了审计跟踪——下游系统看到的是用户令牌,而不是 MCP 服务器,使得无法将操作归因于服务器;(2)它绕过了 MCP 服务器自己的访问策略;(3)如果下游 API 比用户的身份更信任 MCP 服务器的身份,它会创建混淆代理漏洞;(4)如果 MCP 服务器被入侵,攻击者将获得对所有连接的下游服务的转发用户令牌的访问权限。

MCP 访问令牌应该有多短?

OWASP GenAI 指南建议令牌的生命周期以分钟而不是小时或天来衡量。较短的令牌生命周期限制了令牌被盗或会话被劫持时的利用窗口。每次工具调用都应重新验证令牌的签名、受众和到期时间——而不是依赖于会话开始时的缓存验证。

阿尔西亚是 FlowHunt 的一名 AI 工作流程工程师。拥有计算机科学背景并热衷于人工智能,他专注于创建高效的工作流程,将 AI 工具整合到日常任务中,从而提升生产力和创造力。

阿尔西亚·卡哈尼
阿尔西亚·卡哈尼
AI 工作流程工程师

您的 MCP 身份验证架构是否安全?

我们的安全团队根据 OWASP GenAI 标准评估 MCP 身份验证配置、令牌处理和授权流程。在攻击者发现之前识别漏洞。

了解更多

MCP 安全检查清单:OWASP 安全 MCP 服务器部署的最低标准
MCP 安全检查清单:OWASP 安全 MCP 服务器部署的最低标准

MCP 安全检查清单:OWASP 安全 MCP 服务器部署的最低标准

OWASP GenAI 安全项目定义了安全 MCP 服务器部署的五类最低标准。使用此检查清单在投入生产之前评估您在身份认证、隔离、工具、验证和部署方面的当前状况。...

2 分钟阅读
MCP Security Security Checklist +3
MCP 服务器安全:你需要了解的 6 个关键漏洞(OWASP GenAI 指南)
MCP 服务器安全:你需要了解的 6 个关键漏洞(OWASP GenAI 指南)

MCP 服务器安全:你需要了解的 6 个关键漏洞(OWASP GenAI 指南)

MCP 服务器暴露了一个独特的攻击面,结合了传统 API 风险和 AI 特定威胁。了解 OWASP GenAI 识别的 6 个关键漏洞——工具投毒、跑路攻击、代码注入、凭证泄露、过度权限和隔离不足。...

2 分钟阅读
MCP Security AI Security +3
Authenticator App MCP 服务器
Authenticator App MCP 服务器

Authenticator App MCP 服务器

Authenticator App MCP 服务器使 AI 代理能够安全地访问 2FA 代码和密码,简化了自动化登录流程和跨平台凭据管理,同时保持强大的安全实践。...

2 分钟阅读
MCP Security +5