MCP 安全:在经历 95 次生产环境故障后的心得体会

我曾以为安全很简单。更新依赖。使用 HTTPS。不要硬编码密钥。

我错了。

在经历了 95 次生产环境故障和 1,800 小时的开发后,我意识到 Model Context Protocol (MCP) 的安全性与众不同。它不像标准的 REST API 安全。

MCP 带来了新的风险,因为客户端是 LLM,而不是人类。

以下是保护你的 MCP 服务器安全必须了解的内容。

1. MCP 威胁模型

在 REST 中,你确切地知道是谁在调用你的 API。而在 MCP 中,LLM 充当了中间人。这改变了一切:

  • LLM 可能会幻觉出工具调用或参数。
  • 用户不会直接调用工具。他们与 LLM 对话,然后由 LLM 与你的服务器对话。
  • 恶意客户端可能会在发现(discovery)阶段探测你服务器中隐藏的工具。

你面临的最大威胁不仅仅是黑客。还可能是一个出于好意但犯了错、导致系统崩溃的 LLM。

2. API 密钥管理

许多开发者为了图方便,会将 API 密钥放在查询参数(query parameters)中。这是一个错误。查询参数会出现在每一个服务器日志和代理中。

请遵循以下规则:

  • 使用 Header 身份验证(Authorization: Bearer)。
  • 避免在 JSON Body 中传递密钥。
  • 为每个客户端签发不同的 API 密钥。这有助于你追踪使用情况,并在不影响整体运行的情况下撤销访问权限。

3. 严格的输入验证

LLM 会猜错。它们会发送错误的类型和额外的参数。你必须验证每一次调用:

  • 首先检查工具名称是否存在于你的列表中。
  • 拒绝带有额外参数的调用。不要只是忽略它们。
  • 精确匹配参数类型。不要进行数据类型强制转换(coerce)。
  • 为字符串和数组设置严格的大小限制,以防止内存崩溃。
  • 清理(Sanitize)所有文件路径,以防止目录遍历攻击。

4. 分层速率限制

一个用户提示词(prompt)可能会同时触发十次工具调用。这可能在几秒钟内耗尽你的连接池。

使用三层防御:

  • 基于 API 密钥的限制,用于控制客户端的使用量。
  • 基于 IP 的限制,用于阻止暴力破解攻击。
  • 并发连接限制,用于在突发流量期间保持服务器运行。

5. Prompt 注入风险

用户可以诱导 LLM 调用具有破坏性的工具。如果用户告诉 LLM 删除所有笔记,LLM 真的可能会这么做。

保护措施:

  • 将读操作和写操作分离。
  • 对于任何删除或更新操作,都需要用户手动确认。
  • 为你的数据库用户遵循最小权限原则。

安全是一个持续的过程。从更好的密钥管理和严格的验证开始。这些步骤可以解决大部分问题。

Source: https://dev.to/kevinten10/mcp-security-what-i-learned-securing-my-mcp-server-after-95-production-outages-3hc0

Optional learning community: https://t.me/GyaanSetuAi