跳转到主要内容

category

引言


目的和范围


本文档提供了模型上下文协议(MCP)的安全考虑,补充了MCP授权规范。本文档确定了特定于MCP实施的安全风险、攻击媒介和最佳实践。
本文档的主要受众包括实施MCP授权流的开发人员、MCP服务器操作员和评估基于MCP的系统的安全专业人员。本文档应与MCP授权规范和OAuth 2.0安全最佳实践一起阅读。


攻击和缓解措施


本节详细描述了对MCP实现的攻击,以及潜在的对策。
 

困惑的副问题


攻击者可以利用MCP服务器代理其他资源服务器,从而创建“混淆代理”漏洞。
 

术语

  • MCP代理服务器:将MCP客户端连接到第三方API的MCP服务器,提供MCP功能,同时将操作委派给第三方API服务器,并作为单个OAuth客户端。
  • 第三方授权服务器:保护第三方API的授权服务器。它可能缺乏动态客户端注册支持,要求MCP代理对所有请求使用静态客户端ID。
  • 第三方API:提供实际API功能的受保护资源服务器。访问此API需要由第三方授权服务器颁发令牌。
  • 静态客户端ID:MCP代理服务器在与第三方授权服务器通信时使用的固定OAuth 2.0客户端标识符。此客户端ID是指作为第三方API客户端的MCP服务器。对于所有MCP服务器到第三方API交互,无论哪个MCP客户端发起请求,该值都是相同的。


架构和攻击流程


正常的OAuth代理使用(保留用户同意)



恶意OAuth代理使用(跳过用户同意)



攻击描述


当MCP代理服务器使用静态客户端ID向不支持动态客户端注册的第三方授权服务器进行身份验证时,可能会发生以下攻击:

  1. 用户通过MCP代理服务器正常认证,访问第三方API
  2. 在此流程中,第三方授权服务器在用户代理上设置一个cookie,表示同意静态客户端ID
  3. 攻击者随后向用户发送一个恶意链接,其中包含一个精心编制的授权请求,该请求包含一个恶意重定向URI以及一个新的动态注册的客户端ID
  4. 当用户点击链接时,他们的浏览器仍然有来自之前合法请求的同意cookie
  5. 第三方授权服务器检测到cookie并跳过同意屏幕
  6. MCP授权码被重定向到攻击者的服务器(在动态客户端注册期间在特制的redirect_uri中指定)
  7. 攻击者在未经用户明确批准的情况下,将窃取的授权码交换为MCP服务器的访问令牌
  8. 攻击者现在可以作为受损用户访问第三方API


缓解


使用静态客户端ID的MCP代理服务器在转发到第三方授权服务器之前,必须获得每个动态注册客户端的用户同意(这可能需要额外的同意)。


通证(Token Passthrough)

 


“令牌传递”是一种反模式,即MCP服务器接受来自MCP客户端的令牌,而不验证令牌是否正确颁发给MCP服务器并“传递”给下游API。


风险


授权规范中明确禁止令牌传递,因为它引入了许多安全风险,包括:
 

安全控制规避
  • MCP服务器或下游API可能实现重要的安全控制,如速率限制、请求验证或流量监控,这些控制取决于令牌受众或其他凭证约束。如果客户端可以直接通过下游API获取和使用令牌,而无需MCP服务器对其进行正确验证或确保令牌是为正确的服务颁发的,那么它们就绕过了这些控制。

问责制和审计追踪问题
  • 当客户端使用上游颁发的访问令牌进行呼叫时,MCP服务器将无法识别或区分MCP客户端,该令牌可能对MCP服务器不透明。
  • 下游资源服务器的日志可能会显示来自不同身份的不同来源的请求,而不是实际转发令牌的MCP服务器。
  • 这两个因素都使事件调查、控制和审计变得更加困难。
  • 如果MCP服务器传递令牌而不验证其声明(例如角色、特权或受众)或其他元数据,则拥有被盗令牌的恶意行为者可以将服务器用作数据泄露的代理。

信任边界问题
  • 下游资源服务器向特定实体授予信任。这种信任可能包括对起源或客户行为模式的假设。打破这种信任边界可能会导致意想不到的问题。
  • 如果令牌被多个服务接受而没有经过适当的验证,则攻击者可以使用令牌访问其他连接的服务。
  • 未来兼容性风险
  • 即使MCP服务器今天作为“纯代理”启动,它也可能需要在以后添加安全控制。从适当的令牌受众分离开始,可以更容易地发展安全模型。


缓解


MCP服务器不得接受任何未明确为MCP服务器颁发的令牌。


会话劫持

  • 会话劫持是一种攻击向量,其中服务器向客户端提供会话ID,未经授权的一方能够获得并使用同一会话ID来模拟原始客户端并代表其执行未经授权操作。


会话劫持提示注入




会话劫机模仿



 


攻击描述


当您有多个处理MCP请求的有状态HTTP服务器时,可能会出现以下攻击向量:

会话劫持提示注入
  1. 客户端连接到服务器A并接收会话ID。
  2. 攻击者获得现有的会话ID,并使用所述会话ID向服务器B发送恶意事件。
  3. 当服务器支持重新交付/可恢复流时,在收到响应之前故意终止请求可能会导致原始客户端通过服务器发送事件的GET请求恢复请求。
  4. 如果特定服务器因工具调用(如通知/tools/list_changed)而启动服务器发送的事件,这可能会影响服务器提供的工具,客户端最终可能会使用他们不知道启用的工具。
  5. 服务器B将事件(与会话ID关联)排队到共享队列中。
  6. 服务器A使用会话ID轮询队列中的事件,并检索恶意负载。
  7. 服务器A将恶意负载作为异步或恢复响应发送到客户端。
  8. 客户端接收恶意负载并对其采取行动,从而导致潜在的危害。

会话劫持模仿
  • MCP客户端与MCP服务器进行身份验证,创建持久会话ID。
  • 攻击者获取会话ID。
  • 攻击者使用会话ID呼叫MCP服务器。
  • MCP服务器不检查其他授权,并将攻击者视为合法用户,允许未经授权的访问或操作。


缓解


为防止会话劫持和事件注入攻击,应实施以下缓解措施:

  • 实施授权的MCP服务器必须验证所有入站请求。MCP服务器不得使用会话进行身份验证。
  • MCP服务器必须使用安全、非确定性的会话ID。生成的会话ID(例如UUID)应使用安全的随机数生成器。避免攻击者可能猜到的可预测或连续的会话标识符。轮换或过期会话ID也可以降低风险。
  • MCP服务器应该将会话ID绑定到用户特定的信息。在存储或传输会话相关数据时(例如,在队列中),将会话ID与授权用户独有的信息(如他们的内部用户ID)结合起来。使用类似<user_ID>的密钥格式:<session_ID>。这确保了即使攻击者猜测会话ID,他们也无法冒充另一个用户,因为用户ID是从用户令牌中导出的,而不是由客户端提供的。
  • MCP服务器可以选择利用其他唯一标识符。