经典MCP服务器漏洞如何威胁整个AI代理系统

本文深入分析了Anthropic SQLite MCP服务器中的SQL注入漏洞,该漏洞可导致存储提示词注入、数据泄露和代理工作流劫持,并提供了具体修复方案和安全建议。

为什么经典MCP服务器漏洞会威胁整个AI代理系统

关键要点

  • 供应链影响范围广泛:Anthropic存在漏洞的SQLite MCP服务器在被归档前已被分叉超过5000次。这意味着未修补的代码现在存在于数千个下游代理中——其中许多可能已在生产环境中运行—— silently继承SQL注入风险,任何攻击载荷都会在整个代理中传播。
  • SQLite MCP服务器漏洞可能影响数千个AI代理:传统的SQL注入为存储提示词注入开辟了新路径,使攻击者能够直接操纵AI代理,显著提高攻击成功率。
  • SQL注入漏洞通过隐式工作流信任实现权限提升:AI代理通常信任内部数据(无论是来自数据库、日志条目还是缓存记录),代理通常将其视为安全数据。攻击者可以利用这种信任嵌入提示词,随后让代理调用强大工具(电子邮件、数据库、云API)来窃取数据或横向移动,同时绕过早期的安全检查。
  • 无补丁计划,开发者必须自行修复:使用未修补分叉的组织面临重大的运营和声誉风险,包括潜在的数据暴露和服务中断。本文提供了推荐的修复清单以帮助缓解漏洞。

漏洞详情

Trend™ Research发现了一个简单但危险的缺陷:Anthropic参考SQLite模型上下文协议(MCP)服务器实现中存在经典的SQL注入(SQLi)漏洞。尽管GitHub仓库已于2025年5月29日归档,但在此之前已被分叉或复制超过5000次。需要注意的是,该代码明确标注为参考实现,不适用于生产环境。

存在漏洞的代码允许潜在攻击者运行未经授权的命令、注入恶意提示词、窃取数据并劫持AI代理工作流。在本博客中,我们研究了漏洞所在位置、其影响以及如何缓解。

漏洞位置

漏洞在于源代码处理用户输入的方式。它直接将未净化的用户输入连接到SQL语句中,然后由Python的sqlite3驱动程序执行——没有过滤或验证。核心SQL注入漏洞(无参数化输入)如图1所示。

这个缺陷造成了严重的安全风险,特别是为SQL注入(SQLi)创造了完美条件,攻击者可以将恶意查询嵌入系统。

OWASP的SQL注入防护备忘单十多年来一直保持相同的#1建议——使用参数化查询。这通过设计防止SQLi攻击,允许数据库区分代码和数据。忽视这一最佳实践重新开启了所有经典SQL攻击——身份验证绕过、数据泄露、篡改,甚至通过SQLite虚拟表技巧实现任意文件写入。

简单SQL注入如何劫持支持机器人

我们在此说明如何利用此漏洞。在我们的示例中,一个支持AI代理从SQLite MCP服务器拉取工单。客户通过Web表单提交工单,而特权支持工程师(或机器人)对所有标记为"open"的工单进行分类。图2显示了当攻击者使用存在漏洞的SQLite MCP服务器将SQL注入载荷潜入支持AI代理时发生的情况。

以下是攻击展开的逐步分析:

  1. 攻击者提交工单

    图3显示了当攻击者控制的body字段包含注入的SQL语句时的完整SQL查询。合法的支持工单请求将创建在第5行结束的SQL语句。然而,注入的内容(第5至11行高亮显示)用虚假支持工单条目关闭第一个SQL语句,并创建包含恶意存储提示词的新条目。

  2. 恶意提示词通过存在漏洞的SQLite MCP服务器存储

    这相当于LLM环境中的存储XSS攻击,通常称为存储提示词注入,是LLM环境中众所周知的顶级风险。SQLite MCP服务器中的漏洞允许代理以"open"状态存储恶意提示词,有效绕过任何后端安全防护栏,这些防护栏本应对"pending tickets"进行提示词注入检查。

  3. 支持工程师或机器人使用AI代理对"open"工单进行分类

    在分类过程中,通过AI代理,支持工程师或机器人读取包含存储恶意提示词的工单,就像它是有效条目一样。

  4. AI模型遵循提示词中的指令

    存储的提示词引导LLM调用内部工具,如电子邮件客户端或其他MCP服务器,这些在特权上下文中可用且被允许。在我们的示例中,它将客户数据(customer.csv)发送到攻击者的电子邮件(attacker@evil.com)。

由于电子邮件MCP工具以提升的权限运行,且分类工作流盲目信任任何标记为"open"的工单,单个注入的提示词结合存储提示词注入可以通过横向移动或数据泄露危害系统。

在依赖MCP服务器存储和检索信息的AI代理环境中,看似微不足道的SQLi错误不再仅仅是数据层错误,而成为存储提示词注入的跳板,引导代理执行特权操作、自动化数据窃取和执行横向移动。

披露和当前状态

2025年6月11日,我们根据负责任披露准则私下向Anthropic报告了此问题。Anthropic回复称该仓库是归档的演示实现,因此漏洞被视为"超出范围"。截至撰写时,根据GitHub问题#1348的讨论,没有计划发布补丁。此外,Anthropic的所有参考实现也已被归档。

快速修复清单

由于归档仓库没有官方补丁计划,保护其实现免受此漏洞影响的任务主要落在开发者和团队身上。我们在此列出了快速修复清单,用于识别和修补开发者自己的SQLite MCP服务器分叉或部署中的漏洞:

  • 手动修复存在漏洞的SQLite MCP服务器,通过将f-strings替换为占位符:检查您是否在2025年5月29日前分叉了Anthropic的sqlite MCP服务器,或者是否使用了任何归档版本。如果找到,定位每个_execute_query调用并强制执行参数化执行,如下所示:
1
2
3
4
5
6
7
8
# 存在漏洞的代码
results = db._execute_query(arguments["query"])

# 快速修补
sql, params = arguments["query"], tuple(arguments.get("params", []))
if ";" in sql:           # 简单的单语句防护
   raise ValueError("stacked queries blocked")
results = db._execute_query(sql, params)  # 使用参数化输入
  • 为SELECT … FROM {table}结构设置表名白名单
  • 通过sqlite3配置禁止堆叠语句(isolation_level=None禁用隐式自动提交,但仍需要输入验证)
  • 监控离开LLM边界的异常提示词(生成的SQL中出现意外的SELECT * FROM users,或分类代理突然爆发电子邮件)

结论和建议

此事件以新的紧迫性强化了一个古老的教训——一旦经典输入净化错误位于AI代理之后,它们就不会局限于数据层。MCP服务器中的单个非参数化字符串可以通过数千个下游分叉级联,进入专有代码库,并最终在特权上下文中触发自动化工作流。当攻击者可以将教科书式的SQLi转变为存储提示词注入时,每个后续的LLM调用都可能被攻击者的指令控制——无论是读取客户记录、发送电子邮件还是渗透到相邻系统。

结论很明确。如果我们允许昨天的Web应用错误溜进今天的代理基础设施,我们就为攻击者提供了一条从SQL注入到完全代理妥协的轻松路径。关闭这个差距需要严格的编码标准、自动化的供应链监控和运行时防护栏,这些防护栏应假设任何存储内容(无论其来源如何)都可能是恶意的。

除了快速修复清单外,以下是帮助防止此类漏洞的最佳实践:

  • 重新审视OWASP的SQL注入防护备忘单:如前所述,OWASP长期推荐参数化查询作为防御SQLi的#1方法。这应被视为基础实践,特别是在与LLM或基于代理的系统集成时。
  • 审计AI代理工作流中的隐藏信任假设:如果AI代理默认将内部数据视为安全数据,它可能容易受到存储提示词注入的攻击。审查AI何时以及如何读取、解释和处理用户生成或系统存储的输入。
  • 限制特权上下文中的工具访问:AI代理不应无限制地访问电子邮件、文件系统或外部API等工具。引入验证步骤、批准或沙盒限制以在发生利用时限制影响。
  • 监控异常:注意可疑提示词、意外SQL命令或不寻常的数据流——如代理在标准工作流之外触发的出站电子邮件。
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计