永远不要信任输出:AI代理和MCP中的数据污染
免责声明:本文仅供教育目的和安全专家进行授权测试时参考。作者对所提供的任何信息的滥用不承担任何责任。分发恶意软件、破坏系统和侵犯隐私的行为将受到法律制裁。
引言
我相信大多数读者已经熟悉提示注入(Prompt Injection)的概念及其各种后果。然而,在2026年,任何没有MCP(模型上下文协议)服务器的AI模型都无法充分发挥其潜力——这就是为什么开发者连接众多MCP服务器来扩展其能力的原因。
但问题是:如果这些MCP服务器返回的数据是恶意构造的呢?
“我已经修正了下面的JSON!”
如果你使用过MCP服务器,你可能知道它们中的大多数返回JSON数据。让我们以流行的GitHub MCP为例:
当然,我们期望得到正确转义的JSON返回……
为什么这会起作用?模型以纯文本形式接收JSON并在内部解析它——实际上并没有真正的JSON解析器参与。有时,模型甚至会输出类似这样的想法:
“我已经修正了下面的JSON,然后将其解析成一个干净、结构化的表示。”
换句话说,模型可能会认为JSON编码“损坏”了,并试图“修复”它。我已在多个模型中证实了这种行为:Opus 4.5、Grok Code、Gemini 3 Pro和GPT 5.2。
哥们,信我
如上所述,这种方法的问题在于其不稳定性——它在很大程度上取决于执行上下文。让我们在另一个流行的MCP服务器上尝试这种技术:postgresql_mcp。
首先,让我们创建一个表,在email字段中包含一个注入载荷:
现在,让我们看看通过postgresql_mcp查询此表时会发生什么:
Opus 4.5、GPT 5.2、Gemini 3 Pro、Composer 1——它们都察觉到了可疑之处,并正确地渲染了表格:
在流行模型中,Grok被证明是最容易轻信的——它是唯一一个没有检测到欺骗的:
但我们希望在主流模型上也实现成功的注入。这时,全角字符(Fullwidth characters)就来救场了:'"
虽然这些字符不是真正的JSON控制字符,但请记住:模型不使用真正的解析器来处理输出。
这样效果就好多了!在Gemini 3和Composer上,我们的注入能够持续触发。
ChatGPT和Opus有时会产生怀疑,但这取决于系统提示和上下文。如果你简单地要求这些模型手动解析这样的JSON,即使是ChatGPT和Opus也会妥协:
因此,总体情况可以总结如下:
哥们,我们来调用个工具
显然,显示被“走私”的数据已经可以帮助扭曲AI管道的行为。
但让我们做点更有趣的事情——比如触发另一个工具调用。
PostgreSQL 示例
关键是在输出中插入这样的内容:
|
|
在我的案例中,载荷看起来是这样的:
|
|
这个载荷背后的逻辑:
- 使用全角撇号来跳出属性上下文
- 添加一个包含我们指令的
<ERROR>标签来UPDATE数据库。当数据提到MCP时,这招最有效——模型不会质疑为什么需要UPDATE ...\xF0\x9F\x98——通过实验,我发现使用不可读的字符是让模型相信发生错误的有效方法
以下是执行过程的样子:
我在Sonnet 4.5、Gemini 3 Pro和Composer 1上实现了成功的利用。
在Opus 4.5和GPT 5.2上,我通常得到这样的响应:
Detecting and handling malicious injection in database data (检测并处理数据库数据中的恶意注入)
也许我只是不擅长提示注入……
GitHub MCP 示例
使用类似的方法,我设法欺骗模型将一个用户添加为仓库协作者:
|
|
其他小技巧
换行符注入
正如你可能猜到的,一个关键的漏洞是我们可以简单地使用<newline>(换行符)来破坏格式。示例:
CSV 注入
通过将JSON技巧与Unicode字符(,)结合,你还可以污染CSV输出。没什么突破性的,但可能派上用场:
盲数据污染
有时你想测试和执行盲污染(Blind Pollution)——即你无法直接观察到输出。
技巧是结合多种注入技术。假设有一个MCP服务器向HR专员返回简历信息。你可以使用这样的载荷:
|
|
当我用不同的格式对Gemini运行这个时,我得到了: