跳到主要内容

工具组合沙箱逃逸:当三个安全工具组合成数据泄露时

· 阅读需 11 分钟
Tian Pan
Software Engineer

安全审查分别批准了这三个工具。对客户数据库的只读访问被评估为低风险,因为智能体(agent)只能查看记录而不能修改。发送邮件给自己(Send-email-to-self)被评估为低风险,因为收件人被硬编码为一个服务账号邮箱,且智能体已被授权向该邮箱写入。模板渲染(Template-render)被评估为低风险,因为它是一个不带 I/O 的确定性 Jinja 风格转换。发布三周后,数据丢失防护(DLP)仪表板标记了出现在一个有两百名员工可读的 Slack 频道中的客户 PII。事后分析(post-mortem)发现泄露源于智能体将这三个工具组合成了一个没有任何单一 ACL 授权的链路:读取客户记录,通过模板渲染,将结果发送到它自己的服务账号,而该邮箱又自动转发到了该频道。

没有一个工具被滥用。没有提示词注入(prompt injection)绕过任何检查。智能体完全按照其工具目录所说的那样执行,而这种组合产生了一种安全审查从未被要求评估的能力。

这种形式是大多数智能体权限故障在生产环境中的表现,且其结构与主导讨论的 LLM 安全故事截然不同。提示词注入是一个词汇问题——攻击者将指令混入上下文窗口。工具组合泄露是一个语法问题——规划器(planner)将授权的动词组合成一个句子,而其中的含义是任何单个动词都不具备的。对工具进行单独审计可以捕捉第一类漏洞,但它无法捕捉第二类。

权限面是组合下的闭包,而非 ACL 的并集

审查智能体工具目录的工程师往往将权限面想象成一个检查清单:工具 A 读取 X,工具 B 写入 Y,工具 C 调用 API Z。权限面看起来像这些行的并集。实际上,权限面是这些行在组合下的闭包——规划器可以从它们构建的每一个链条,包括目录作者从未列举过的链条。

闭包扩张很快。拥有十个工具且规划器愿意按长度为五的序列调用它们时,搜索空间达到数十万。大多数链条是无意义的。一小部分但非零的比例会将“读-写-渲染-邮件”这些原语转化为权限提升,而逐个工具的审查流程无法发现这一点,因为该流程是以单行而非图(graph)为基准的。

最近披露的 Microsoft 365 Copilot 中的 EchoLeak 漏洞(CVE-2025-32711,已于 2025 年 5 月修复)是一个典型案例。底层功能——对用户邮箱的 RAG 检索、模板渲染的响应、带有外部 URL 的图像渲染——在单独看来都不是可利用的。攻击者构造的邮件导致智能体检索敏感上下文,将其嵌入图像 URL 的查询字符串参数中,并发出一条响应,其渲染导致用户的浏览器向攻击者控制的主机执行 GET 请求。三个无害的功能,一个零点击的数据外泄链条,不需要任何恶意软件。

生产团队将不断发现这一问题的各种变体。这种链路很少像 EchoLeak 那样优雅,也很少涉及安全研究员编写 CVE——它通常表现为 DLP 警报、智能体通过链式操作“查询采购订单”和“批准额度”支付的供应商账单,或者是客服机器人因为两个检索工具和一个模板工具组合成了“总结你能找到的一切”而在公开回复中引用了内部定价。

来源与汇聚点,而非逐次调用权限

捕捉组合攻击的防御原语不是更严格的逐工具 ACL。而是在智能体推理过程中随数据移动的标签,以及在执行前评估建议链的数据流图的策略引擎。

信息流控制(IFC)是这一思想的正式名称,关于它的文献早在 LLM 出现前几十年就已存在。Microsoft Research 在 2025 年论文《使用信息流控制保障 AI 智能体安全》(Securing AI Agents with Information-Flow Control)中提出的 FIDES 系统,是首批具体的规划器设计之一,它通过工具输出传递机密性和完整性标签,并使用这些标签来闸口下游操作。它为生产代码建议的形态大致如下:

  • 每个工具输出都标有来源标签——customer_piiinternal_onlyexternal_untrusted——且标签会传播到任何消耗该值的操作。
  • 每个工具输入都声明它将接受的标签,并在调用前进行汇聚点(sink)检查。
  • 组合策略声明哪些来源–汇聚点组合是被禁止的,无论是由哪些工具产生或消耗的。

诸如“任何读取 customer_pii 并生成 external_bound 制成品的链条都会被拒绝”之类的规则,即使规划器通过安全团队从未想象过的路径到达该链路,也能捕捉到“读取-渲染-邮件”外泄。它之所以能推广,是因为规则是基于数据流图而非工具目录的,而且即使目录增长,图也能保持在较小规模。

这条规则不需要手动编写。静态分析工具进行污点传播(taint propagation)已有几十年历史——Sonar、Snyk、Apiiro、LDRA 工具链——一旦你将工具表达为来源/汇聚点原语,在 Java 代码库中标记 SQL 注入的相同“源到汇聚点”推理也能标记智能体追踪中的“PII 到外部”。

针对组合进行红队测试,而非词汇

孤立地对每个工具进行模糊测试(fuzzing)的红队演练是在审计词汇表。而搜索工具序列交叉乘积的红队演练则是在审计语言。前者回答的是“是否可以诱导单个工具做出错误行为?”后者回答的是“规划器是否能构建出跨越用户未授权信任边界的句子?”

组合性至关重要。与列举每一条链相比,以下几种实践方法更具扩展性:

  • 能力图搜索。 构建一个有向图,其中边将工具输出连接到兼容的工具输入。运行一个可达性查询:从任何标记为 external_untrusted 的源到任何标记为 external_bound 的汇(sink)。任何路径都是潜在的漏洞利用链。根据标签、现实的提示词预算以及模型实际会调用的内容进行剪枝。
  • 提示词形态的模糊测试。 生成对抗性提示词,目标是诱导规划器遍历被标记的路径。评分标准应取决于非预期的汇(sink)是否被触发,而不是模型是否输出了可疑文本。Promptfoo、DeepTeam、Microsoft 的 AI Red Teaming Agent 以及 Galileo 的红队库都支持这种形式的测试。
  • 工具目录变更的差异评审(Differential review)。 每一个添加或修改工具的 PR 都会重新运行可达性查询。新的链路会作为策略报告中的差异点亮。那种“六个月后加入的下一个工具”导致失败的模式——即一个新的 MCP 服务器静默地将现有工具扩展为危险的新组合——将变成一个 CI 信号,而不是事后剖析时的发现。

OWASP 的 MCP Top 10 和 OWASP Agentic AI Security Cheat Sheet 现在都将工具链组合视为一类核心问题。这些文档中汇集的防御技术包括:在智能体控制面(Microsoft 的 Securing MCP 工作称之为“智能体控制面”)进行运行时策略强制执行、对工具输出进行出口过滤,以及基于链而非基于调用的授权。

组织层面的失效模式

上述技术防御手段是可行的。而组织层面的失效模式则更难对付。

大规模应用中的工具由不同的团队拥有。Customer-DB-Read 由数据平台团队负责,他们基于“分析师可以读取客户记录”的上下文进行思考。Send-Email-To-Self 由平台团队负责,他们基于“内部服务需要给自己发送状态邮件”的上下文进行思考。Template-Render 由第三个团队负责,他们基于“静态网站生成器将 Markdown 转换为 HTML”的上下文进行思考。这些团队对自己工具的理解都没有错。但没有哪个团队拥有这些工具的组合权。

当一个链路导致数据外泄时,每个相关的团队都可以正确地说他们的工具没有问题,而本应捕获该链路的组合策略却无人负责。同样的动态也出现在安全评审中:每个团队的威胁模型都围绕该团队的工具展开,安全评审员批准了该工具,而本可以捕获该链路的跨工具推理却不在任何人的任务队列中。

组织上的解决办法是指定一个组合表面的所有者,其在结构上与工具作者分离。正在大规模交付智能体的生产团队正趋向于一种控制面形式:一种策略服务,智能体在执行任何工具链之前必须咨询该服务,该服务由安全工程部门拥有,他们有权拒绝工具作者认为没问题的链路。控制面能看到单个工具作者看不到的东西——规划器尝试的每个链路的数据流图——它是架构中唯一能连贯落地组合策略的地方。

这种模式呼应了成熟企业处理 Kubernetes 准入控制或服务网格策略的方式。单个工作负载的作者对管理横向关注点(cross-cutting concerns)的策略没有投票权;一个集中拥有的策略引擎会根据规则评估每个工作负载。智能体领域的等效做法是将同样的想法应用于工具执行。

首先构建什么

大多数阅读本文的团队在下个季度都不会交付 FIDES 风格的信息流控制(IFC)规划器。实际的操作顺序大致如下:

  1. 将工具目录作为图进行盘点。 列出每个工具及其输入标签、输出标签。你第一次做这件事时,标签通常是错的——记录标签的行为本身会迫使对话产生,从而得出真实的标签。
  2. 添加明显的“源到汇(source-to-sink)”规则。 比如:PII 到外部、仅限内部到用户可见、客户源数据到公共频道。这些规则能捕获大多数生产环境中的数据外泄,因为大多数泄露正是这种形式。
  3. 将规则接入智能体运行时作为拒绝列表,而不仅仅是日志系统。 一个违反时仅报警的策略等同于一个带着违规上线的策略。控制面必须是带内的(in-band),有权在“汇”触发之前终止链路。
  4. 在 CI 中加入针对工具目录变更的规则。 每个新工具都是图中的一个新节点;每个 PR 都会重新评估可达性,并报告任何跨越禁止的“源到汇”对的新边。
  5. 然后再讨论正式的 IFC。 一旦简单的规则就位,并且团队在哪些地方存在过度近似或欠近似方面有了经验,正式版本就成了一种优化,而不是推倒重来。

值得借鉴的架构认识是:一个智能体的权限表面是其工具目录在组合下的闭包。针对每个工具的 ACL 是在审计目录的词汇。威胁存在于目录的语法中,而单独审计工具的团队是在审查单词,与此同时,规划器正在构建句子。

References:Let's stay in touch and Follow me for more thoughts and updates