治理更新于 2026-08-22 · 版本 1.0

什么是 MCP 安全?

MCP 安全是防止 Model Context Protocol(模型上下文协议)服务器成为进入系统最便捷通道的关键。该协议规范了智能体如何发现和调用工具;但它并不决定谁可以调用它们、它们可以访问什么,或者当工具描述变得具有敌意时会发生什么。这些决策存在于服务器中:身份验证、来源和传输验证、严格限制范围的工具、速率限制以及审计追踪。

证据: 生产环境置信度: 来源: 生产系统来源: 个人经验来源: 行业观察

定义

MCP 安全是应用于 Model Context Protocol 服务器及其客户端的一组控制措施——包括身份验证和授权、来源和传输验证、工具范围限定、输入和输出处理、速率限制以及审计——从而确保向 AI 智能体开放能力不会暴露其背后的系统。

核心要点

  • MCP 规范的是管道,而不是信任:每个服务器都决定自己的安全态势。
  • 工具描述对模型而言是不可信的输入——它可以包含指令,并且在批准后可能会发生变化。
  • 本地 stdio 服务器和远程 HTTP 服务器具有不同的威胁模型;其危险的错误也各不相同。
  • 来源检查和速率限制属于服务器端职责,因为客户端并不在您的控制之下。
  • “只读”是实现的一种属性,绝非工具名称所能决定。

背景

MCP 为智能体提供了一种统一的方式来发现和调用能力。这种统一性既是价值所在,也是风险所在:一个客户端可以指向多个服务器,而每个服务器都是一个全新的信任决策——在实践中,这往往是由将 URL 粘贴到配置文件中的人做出的。

主要存在两种部署形式。本地 stdio 服务器在用户的机器上以用户自身的权限运行:没有网络边界,因此问题在于它可以读取什么以及它是否会向外发送数据。远程 HTTP 服务器是一个公共端点:问题变成了谁在调用、从哪里调用、调用频率如何,以及是否可以诱骗浏览器代表用户调用它。

我们为此知识库运营着这两种形式的实例——一个公共 HTTP 端点和一个已发布的 stdio 包——因此下面描述的控制措施是基于其实际实现方式,而非通用的检查清单。

架构

首先确定暴露级别:公开只读能力、经过身份验证的能力,还是仅限本地。其他所有设计都取决于这个决定,而大多数安全事件都源于那些本不该暴露的服务器。

在执行任何操作之前先验证传输。对于 HTTP 服务器,在处理程序运行之前,根据白名单检查 Origin 标头并拒绝浏览器发起的跨站调用——DNS 重绑定和 CSRF 类型的滥用都是通过这种方式进行的。

只要协议允许,就保持服务器无状态。没有会话存储意味着没有会话固定、没有跨请求污染,也没有调用者之间泄露状态的风险。

严格限制工具的作用域。一个工具,一种能力,不要使用会随参数改变而改变的动词——一个同时支持写入的 'query' 工具,随时可能因为一个特定的参数而导致权限提升。

针对每个调用者进行速率限制,并返回真实的 429 状态码和 Retry-After 标头。会进行重试的智能体(agent)是正常流量;而无限制重试的智能体则是针对您自己后端的拒绝服务(DoS)工具。

记录每一次调用,并保留足够的信息以重建滥用场景——工具、结果、延迟、调用者身份——且不要记录任何可能使日志本身成为泄露源的信息。

在返回过程中,将每个工具的结果都视为不可信内容。从设计上讲,代理外部数据的服务器就是一个间接提示词注入(prompt-injection)通道。

组件

身份验证:对于真正的公开只读数据,无需验证;对于其他任何数据,使用令牌(token)或 OAuth——并且必须记录这一决定,因为“无验证”必须是一种主动选择,而不是疏忽。针对远程服务器的 Origin 和主机验证,应基于实际测量的流量,而不是假定使用 Web 应用的默认设置。针对每个工具的授权:明确该调用者可以调用什么,而不仅仅是他们是否可以连接。在工具边界进行输入验证,其严格程度应与公开 API 相同——因为它的本质就是公开 API。输出整形:仅返回调用者所需的最小内容;绝不直接透传原始的上游负载。速率限制和配额,并提供足够准确的标头,以便行为良好的客户端能够自动退避。审计日志和指标,保留时间应足够长以便于调查,且聚合度应足够高以确保安全保存。服务器自身的供应链卫生:固定依赖项、审查更新、发布来源证明,以便客户端能够确认它们正在与您构建的服务器进行通信。

优势

  • 与它所替代的临时集成相比,一个作用域划分合理的 MCP 服务器具有更小的攻击面:统一的协议、统一的审计点、统一的撤销位置。
  • 无状态和单一职责的工具使得服务器易于推理——安全审查报告一页纸就能写完。
  • 标准的错误和速率限制标头使客户端行为变得可预测,这本身就是一种防御性特征。
  • 因为所有内容都跨越同一个边界,所以测量是顺理成章的:滥用行为和正常使用会出现在相同的日志中,且特征明显不同。

风险

  • 工具“抽毯子”(rug pulls):服务器在审批时表现正常,但在客户端停止询问后更改其工具描述。
  • 作用域过宽的本地服务器:持有用户文件系统和凭据的 stdio 服务器具有完整的智能体能力,且没有网络边界来拦截它。
  • 混淆代理(confused deputy):服务器持有调用者不具备的凭据,因此任何访问该服务器的人都会继承其访问权限。
  • 隐蔽的公开暴露:部署时没有身份验证、没有 Origin 检查且没有速率限制的远程服务器很容易被发现并被随意滥用。
  • 注入中继:从第三方源获取工具输出,并将其作为可信指令传递给模型。

工具与技术

MCP 规范及其传输安全指南——每个服务器都应该能够对照并满足的基线要求。在应用代码运行之前应用的 Origin 白名单和 CORS 配置。速率限制存储(Redis 或同等工具),以哈希处理后的调用者身份而非原始 IP 作为键。结构化请求日志和延迟指标,以便在同一视图中直观查看滥用情况和成本。针对 LLM 应用的 OWASP Top 10,用于应对 MCP 服务器会放大的一系列注入和过度授权(excessive agency)问题。注册表列表和签名发布,以便客户端可以验证它们安装的服务器就是您发布的那个。

示例

  • 该知识库暴露了一个公开的、只读的 HTTP MCP 端点。它在设计上是无状态的,因此无法固定或重放会话;工具仅返回已发布的内容;并且每次调用都会针对哈希处理后的调用者进行速率限制,并返回真实的 429 和 Retry-After。
  • 在为该端点编写 Origin 规则之前,我们首先测量了它自身的流量:几乎所有的请求都没有携带 Origin 标头,没有一个携带 null,而每个确实携带该标头的请求都来自本网站。最终发布的规则遵循了这一测量结果——拒绝来自其他任何地方的浏览器源调用,允许作为实际受众的无标头智能体流量——而不是复制 Web 应用的默认策略。
  • 为该知识库发布的 stdio 包在本地运行,无需凭据,也无需文件系统访问权限,因为它只需要向公开端点发起出站调用。一个什么都不需要的本地服务器,就不应该被赋予任何权限。

常见问题解答

MCP 是让智能体更安全还是更不安全?
单次集成更安全,但总体而言风险更高。统一的协议意味着只需在一个地方进行审查和撤销——但它也降低了将智能体连接到另一个系统的成本,而每一次连接都是一个必须由人做出的全新信任决策。
只读服务器需要身份验证吗?
如果数据是真正公开的,则不一定需要。但您仍然需要速率限制和审计追踪:公开并不意味着免费,一个无限制的公开端点就是一个指向您自己基础设施的放大器。
如果智能体不发送 Origin 标头,为什么还要检查它?
正因为它们不发送。无标头的流量才是合法的受众;而确实携带外部 Origin 的请求则是代表他人操作的浏览器,这恰恰是值得拒绝的情况。
什么是工具“抽毯子”(rug pull),我该如何防范?
指服务器在用户批准时提供良性的工具描述,随后又将其更改。防御措施包括固定服务器版本、在描述更改时重新验证,以及不向远程服务器授予您不会授予代码依赖项的权限。

参考文献