← 返回 一把挂锁通过管道连接到服务器圆筒和齿轮节点的蓝图线条艺术,放大镜覆盖其中一个节点。

MCP 服务器安全:安装前审查工具

安装 MCP 服务器看起来很简单:粘贴一条命令或 URL、重启客户端,一个新工具就出现在你的代理上下文中。但在那个工具名称背后坐着可执行代码、注入到模型上下文窗口的模式、凭证,以及这些凭证能够访问的任何系统。MCP 生态系统仍在成熟,新服务器的审查流程可以说很薄弱。本文给你一份可复用的安装前清单,应用到一个固定的说明性示例,以及对每个步骤的发现和明确的接受/拒绝理由。

安装实际授予什么

安装 MCP 服务器时,你并非在安装被动库。你在授予可执行代码访问你的工具、文件系统,以及通常你的 API 密钥的权限,中间没有大多数客户端向你显示的审查步骤。

这种信任是累积性的和非粒度化的。如 Pluto Security 的实践指南所述,批准一个 MCP 服务器意味着批准其供应链中的每个操作者。没有按组件重新提示。每个启用的 MCP 服务器还在会话开始时将其完整工具列表推入模型的上下文,消耗令牌并削弱注意力。所以你付出两倍代价:一次在安全表面,一次在上下文预算。

在 Claude Code 中,服务器通过 .mcp.json(项目作用域)或 ~/.claude.json(用户作用域)配置,并可以捆绑在也包含钩子、代理、监视器和 bin/ 脚本的插件目录中。插件不是一个瘦包装。它可以到达你的 shell 会话能够到达的任何地方。

威胁模型有三种现实的失败模式:

  • 恶意发布者创建一个看起来像的服务器,出现在注册表中,重定向 API 调用,或默默地泄露数据。
  • 一个有良好意图但经验不足的作者发布一个服务器,它以纯文本形式存储令牌或记录请求体,而没有考虑过。
  • 一个你批准的合法服务器获得更新,新版本引入了后门或扩大了其权限,但没有重新提示你。

这三种情况都在现实中有记录,不是假设。

审查源、出处和更新行为

在你阅读一行代码之前开始。谁发布了这个服务器?包背后是否有可验证的身份?存储库是否有有意义的提交历史,还是它上周才创建并只有一次提交?

Christian Schneider 的防御优先架构指南明确阐述了供应链卫生要求:仅从可信来源安装服务器、验证包签名或哈希值,以及固定依赖项版本而不是接受"最新"。在包接触你的环境之前对其运行 npm audit pip-audit。生成软件物料清单 (SBOM),以便你可以追踪每个依赖项并在 CVE 发布时快速响应。

对于你的审查清单,在源阶段捕获这些:

  1. 确认发布者身份映射到具有历史记录的已知组织或个人。
  2. 检查存储库创建日期和提交频率。单提交存储库值得特别审查。
  3. 钉住您审查过的确切版本。记录提交哈希值或发布标签。
  4. 在依赖关系树上运行 npm audit pip-audit,并记录发现结果。
  5. 检查服务器的更新机制是否在应用更改前验证数字签名。

举例说明:假设您正在审查一个来自有 18 个月提交历史、两个贡献者和 GitHub 上签名发布的发布者的虚拟 mcp-db-connector@1.4.2。npm audit 返回零个高严重性发现。这通过了这个阶段。一个具有匿名发布者、两天前的仓库和无签名发布的服务器则不会。

检查工具、钩子、脚本和网络访问

源出处是基本前提。现在开始阅读。

查看服务器注册的每个工具定义。说明的描述是否与实际实现相匹配?如 Towards Data Science 的 MCP 生存指南所警告的那样,仅因为某个东西被发布为"电子邮件发送者"并不意味着它只发送电子邮件。它可能会记录它们、改写它们或转发到您没有打算的地方。

特别检查这些:

  • 钩子和生命周期脚本:hooks.json 是否注册了前置或后置工具回调?它们做什么?
  • `bin/` 脚本:是否有在安装或调用时执行的 shell 脚本?阅读它们。
  • 出站网络调用:服务器是否拨打任何文档中未提及的端点?在源代码中使用 grep -r "fetch\|axios\|http\|https\|request"
  • 文件系统访问:它是否请求比任务所需更广泛的路径访问?
  • 凭证处理:API 密钥是否被写入磁盘、记录或在声明的目标服务之外的任何地方传输?

SlowMist MCP 安全检查清单将输入验证、API 速率限制和输出编码列为三个最高优先级的控制项。如果服务器没有严格验证自己的输入,无论您是否信任发布者,它都是注入攻击的向量。

清单标记的一个大多数人遗漏的事项:工具描述逐字注入到模型的上下文中。一个恶意或编写不当的描述可以在沙箱本身完整的情况下影响代理在沙箱内的行为。没有模式扫描的沙箱只是半个防御。

测试提示注入和数据边界情况

对于任何涉及生产数据或客户信息的内容,此步骤不是可选的。

通过工具描述的提示注入是一个有文档记录的攻击向量。攻击者在工具的描述字段内嵌入指令,模型将其解释为用户意图。您需要验证服务器的模式不包含嵌入指令,服务器的输出不被信任为下游权威用户输入,以及从一个工具返回的数据不能泄露到单独的会话或用户的上下文中。

在连接服务器到实际凭证前,运行说明性边界情况测试:

  1. 构造一个工具调用,返回包含"忽略之前的指令..."之类内容的响应,并观察主机客户端是否显示或作用于它。
  2. 将超大或格式错误的输入传递给每个已注册的工具,检查服务器是否妥善处理它们或抛出暴露堆栈跟踪的未处理异常。
  3. 如果服务器可以访问多个数据源,验证对源 A 的查询不能返回来自源 B 的数据。

这些是分类测试,不是认证。简短的手动审查可以识别明显的问题。它不能保证不存在微妙的问题。

如果你正在为客户构建AI工具,需要支持审查MCP集成作为更广泛的Claude Code设置的一部分,Seahawk的Claude Code代理服务可以帮助在投入生产前评估整个技术栈。

选择最小凭证范围并隔离流程

审查过服务器并决定它是可接受的后,问题就变成了:你如何运行它?

蓝图线描艺术图,展示围绕中央服务器圆筒的同心权限环、阀门和仪表。

原则是最小权限,毫不妥协地应用。不要因为方便就把你的个人API密钥和完整账户访问权限交给MCP服务器。创建一个凭证,它只拥有文档功能所需的最小权限。如果服务器只需要读取单个S3存储桶的权限,凭证就不应该有写入权限,这是底线。

隔离选项,按成本大致递增排列:

  • 在专用子进程中运行服务器,除了你明确传入的环境变量外,无法访问父shell的其他环境变量。
  • 使用受限网络策略的容器,防止服务器进行任意出站连接。
  • 对于敏感部署,执行供应链检查作为部署门控,并像对待应用代码一样处理MCP服务器的更新。

General Analysis威胁模型说得很好:没有版本锁定的经过审查的市场意味着今天的已审查服务器可能是明天的骗局。隔离和锁定并非冗余。它们防护不同的故障模式。沙箱限制爆炸范围;锁定防止无声漂移。

还值得注意的是:不要在MCP服务器之间共享凭证。令牌传递和共享API密钥意味着一个服务器的泄露会影响凭证接触到的一切。

记录决策并在每次变更时重新审查

你没有记录下来的审查,就相当于根本没有发生过,至少从你未来的自己或你的团队来看是这样。

对于你安装的每个服务器,维护一份决策日志,至少包含:

  • 所审查的精确版本(包版本加上提交哈希或发布标签)。
  • 审查日期。
  • 执行审查的人。
  • 来自审计工具和人工检查的发现。
  • 接受/拒绝的理由。
  • 会触发重新审查的条件(例如任何新的主要版本、工具模式的任何变更、任何触及依赖项的安全公告)。

这不是为了繁琐而繁琐。Schneider的架构指南提出了一个直接的问题,大多数团队都答不上来:"如果MCP服务器的工具描述在用户批准后发生了变化,会发生什么?有人会知道吗?"在大多数默认设置中,答案是否定的。版本锁定加上决策日志就是改变这个答案的方法。

即使没有新版本发布,也要设置日历提醒每季度重新审查一次锁定的服务器,因为围绕它们的威胁环境在代码不变的情况下也在变化。

对于已在生产栈中运行MCP服务器的团队,关于在现有工具旁边管理多个服务器的操作注意事项在我们的生产栈文章中单独涵盖。

可复用的安装前检查清单:接受/拒绝的理由说明

下面是完整的检查清单,按分类优先级排列。在安装任何服务器前应用它。示例发现仅作说明之用;你的结果会有所不同。

#检查说明性发现判定
1发布者身份可验证已知组织,18个月历史记录通过
2仓库创建日期和提交频率活跃,多个贡献者通过
3版本已固定,发布已签名GitHub 上的签名标签通过
4npm audit / pip-audit 清洁零个高严重程度的发现通过
5工具描述与实现相符电子邮件工具仅调用电子邮件 API通过
6无未记录的出站网络调用发现一个未记录的分析 ping拒绝 / 调查
7已审查 Hooks 和 bin/ 脚本不存在 hooks通过
8已强制实施服务器端输入验证已确认严格的模式验证通过
9凭证范围已最小化已创建作用域限制的只读密钥通过
10已应用隔离在受限子进程中运行通过
11决策已记录版本和日期已记录通过
12重新审查触发器已定义在任何架构更改时触发通过

第 6 行说明了为什么要这样做。未记录的分析 ping 本身不一定是恶意的,但它是未记录的,未记录的出站调用是拒绝标准,直到有解释。你向发布者询问、获得明确答案、审查实际发送的内容,然后做出新决策。这就是流程。

FAQ

审查源代码能保证服务器安装后是安全的吗?

不能。代码审查是分类,不是认证。它降低了明显问题的概率:未记录的网络调用、凭证日志记录、恶意工具描述。它不能防护将来更新引入的漏洞(这就是为什么要固定版本并在更改时重新审查)或需要深度安全分析才能发现的微妙逻辑缺陷。

什么是工具中毒,它与 MCP 有什么关系?

工具中毒是指攻击者在工具的名称或描述字段中嵌入恶意指令。由于 MCP 工具架构被逐字注入到模型的上下文中,模型可能会将这些指令解释为合法的指示。在安装前审查架构并检查嵌入的指令片段是安装前阶段的主要缓解措施。

我是否应该以不同的方式审查远程 MCP 服务器和本地服务器?

本地服务器因为直接运行在你的机器上且有权访问你的环境,所以到敏感数据的路径较短。远程服务器引入了网络攻击面和中间人风险。两者都需要相同的检查清单,但本地服务器特别需要关注源代码中的文件系统访问范围和凭证处理,而远程服务器则需要已验证的 TLS、签名验证和符合当前 MCP 规范的 OAuth 2.1 合规性。

我应该如何处理闭源或以二进制形式分发的 MCP 服务器?

如果你无法读取源代码,你就完全依赖于发布者声誉、密码学签名验证和运行时控制(沙盒、网络策略、作用域凭证)。这是一个风险明显更高的态势。对于任何涉及生产数据或客户信息的内容,没有来自已知发布者的可验证签名的闭源二进制文件应该默认拒绝。

什么是 SBOM,我真的需要为 MCP 服务器配备一个吗?

SBOM(软件物料清单)是一份机器可读的清单,包含一个包所包含的每个依赖。对于 MCP 服务器,即使顶层包本身看起来没问题,它也可以让你识别任何传递依赖是否有公开的 CVE。对于低风险的个人工具,这是可选的开销。对于处理敏感数据的生产部署,它是了解你的风险敞口和猜测之间的区别。

这整个审查中最尖锐的警告:在注册表中看起来良性的工具描述在安装后能够引导代理行为的方式与恶意可执行代码一样有效,而大多数客户端不会警告你。读取架构,而不仅仅是 README。

← 返回