目前市面上越来越多的 LLM 客户端开始提供对 MCP 协议的支持。MCP 协议通过统一模型与外部内容的双向通信方式,使 LLM 能够从外界获取信息并操控外部程序。然而在默认情况下,这一能力为大模型应用引入了新的攻击面和威胁。
(我认为 LLM 和 EVM 的智能合约有着相似之处:它们的内部运行机理都独立于传统计算机设备,都需要一个外置程序或设备来中转获取传统信息。这个中转程序在区块链领域被称为预言机,在 LLM 领域则是 MCP。这体现了不同技术领域的概念正在向相似的方向演进。)
# 现状分析
有 MCP 参与的 LLM 应用通常被称为 Agent。它与现有 LLM 应用的本质区别在于:
- 能通过 MCP 获取外部信息
- 能调用 MCP 对外部环境产生影响
你可能会想:"这不就是 tool call 吗?" 确实如此,但 MCP 是对 tool call 的规范化,因此被称为一种 protocol。
目前市面上的 LLM 客户端正逐步实现对 MCP 的支持。以我使用的 Cherry Studio 为例,它支持通过 uv/npx 调用 Python/Node.js 的 MCP 服务,以及远程 SSE 调用 MCP。
我们以一个简单的简单的攻击方法来论证其攻击面
这是一个简单的总结文档的请求:
在 code.txt 中,我写入了劫持模型行为的 payload:
可以看到,模型的行为成功被我劫持了。同理,我可以通过在文档中插入任意恶意内容,调用指定的一个或多个 mcp 服务在目标客户端上执行包括但不限于信息泄漏 / 命令执行的攻击。
由于当前的 MCP 服务主要在本地运行,且客户端通常会自动执行 MCP 请求而不提供用户确认机制,这类投毒攻击很可能会取得较高的成功率。
# 防御原理
最直接的防御方法是在执行 MCP 请求前强制要求用户审批。然而,在需要大量 MCP 请求的对话场景中(如 deepresearch),这种方式会导致用户需要频繁审批上下文。为了实现审批自动化,我们可以利用 LLM 来检测上下文信息的威胁程度。当系统检测到上下文中包含潜在的注入内容时,会触发 alert 变量。模型在执行 MCP 调用前会检查这个 alert 变量 —— 如果发现风险提示,就会拒绝调用并要求用户进行人工审批。
MCP 请求的安全防御流程图:
# 防御实现
防御的触发点在每次导入新的上下文时。通过每次对新上下文的风险识别,可以保证在出现 alert 之前的上下文都是可信的。