超越提示注入
2025年底,安全界不再将间接提示注入视为理论风险。OWASP和NIST将其列为头号威胁。文章指出,输入过滤不足以防御,必须转向行动层验证。通过确定性代码对代理行为进行审计和限制,如合同审核,即使模型被欺骗,也能阻止危险操作。实现行动级别的最小权限、机器身份零信任和边界能力合同。
2025年底,安全界不再将间接提示注入视为理论风险。此前两年,它一直是整洁的实验室演示,直到生产系统开始遭受攻击。OWASP LLM应用十大风险将提示注入列为头号风险,NIST称间接注入是生成式AI最大的安全缺陷,而学术研究人员证明,单封被篡改的电子邮件可在80%的试验中诱使模型泄露SSH密钥,无需用户交互。攻击无需恶意二进制文件、无需网络钓鱼点击、也无需异常登录。代理只是按设计读取内容并采取行动,而内容由攻击者编写。
最具启发性的例子是ForcedLeak。2025年9月,Noma研究人员披露了Salesforce Agentforce平台的一个关键漏洞链(CVSS 9.4):攻击者将恶意指令嵌入常规Web-to-Lead表单的描述字段。文本无害地存在于CRM中,直到员工后来要求AI代理处理该线索,代理忠实地执行了合法查询和攻击者隐藏的有效载荷,将敏感CRM数据泄露到外部服务器。令人夜不能寐的细节是,泄露目标域名仍在Salesforce的信任白名单上,该域名已过期,研究人员以约5美元重新注册。每个安全控制都看到流向信任域名的正常流量,没有异常。
如果你的本能反应是“我们过滤提示注入”,那你在防御错误的外围。输入过滤必要但远远不够。不安的事实是,注入本身不是漏洞,行动才是。而我们称之为“AI安全”的几乎所有内容都针对句子的后半部分。
每个人都在构建的防御
询问大多数企业AI团队如何保护代理,你会得到一致答案:他们净化输入。他们用复杂的指令强化系统提示以忽略冲突指令。他们对传入内容运行分类器以标记对抗模式。有些人采用了前沿实验室发布的更复杂的训练时防御——指令层次结构教会模型对不同来源分配不同的信任,以及强化学习方法在代理上下文中硬化模型对抗注入。
所有这些工作都很好,不应放弃。但注意每种技术的共同点:它们都试图阻止模型被欺骗。它们假设如果我们在输入层使模型足够鲁棒,系统就是安全的。这个假设正是漏洞所在。
我们花了两年时间试图让模型不可欺骗。而幸存在生产中的系统则假设它无论如何都会被欺骗。
为什么输入层是错误的外围
提示注入不是未来模型将缺失的漏洞。它是语言模型工作方式的结构性属性。在推理时刻,模型消耗单个未区分的令牌流。你的指令、检索的文档、工具输出和刚刚获取的网页都是无法区分的通道,坍缩到一个上下文。没有硬件强制边界介于“信任的指令”和“不信任的数据”之间,就像操作系统中内核空间和用户空间之间那样。
这就是为什么代理一旦变得自主,攻击面就会爆炸。只对话的聊天机器人是受控风险。从开放网络检索、读取邮件、查询数据库和调用API的代理,每一轮都会从十几个来源摄取对抗内容,其中任何一个都可能携带指令。研究人员对真实代理生态系统进行的编目已经发现了数百个恶意第三方扩展,它们执行数据泄露和静默注入而用户毫不知情。这些不是实验室奇观,而是生产环境。
所以,如果你不能保证模型永远不会被欺骗——而且你确实不能——那么依赖它永远不被欺骗的架构就建立在沙子上。你需要第二个原则,分布式系统工程师已经理解了几十年的原则。
先验证,再信任
该原则说起来简单做起来难:代理的提议行动应在执行前根据外部确定性策略进行验证,无论代理为何提议。验证器不关心产生该行动的指令是否合法。它不试图检测注入。它问一个不同且更易回答的问题:这个行动就其本身而言是否被允许?
这颠倒了负担。检测巧妙伪装的恶意指令是开放式的,因为对手可以任意创新。检查电汇是否超出硬性美元限额是一个有确定答案的封闭问题。我们将安全决策从攻击者拥有无限自由的地方转移到他们几乎没有任何自由的地方。
关键是,检查必须是确定性代码,而不是另一个模型问“这看起来危险吗?”一旦你要求第二个LLM裁决,你就重新引入了完全相同的漏洞一层之下。执行层是枯燥的、可审计的传统软件,这正是重点。
实践中是这样的。管理采购的代理提议一个行动,运行时合同在真实API被触及之前评估它:
agent_contract.yaml
agent_id: "procurement_executor_07" role: "EXECUTOR" policy: approve_invoice: max_amount_usd: 50000 allowed_vendors: from_approved_registry require_human_above_usd: 10000
运行时,对提议的行动:
ACTION approve_invoice(vendor='Acme', amount=1200000) REJECTED 策略违规: max_amount_usd 提议 1,200,000 / 限额 50,000 行动已丢弃,已通知人工,未发起API调用
凌晨2点14分的注入指令在这里从未起作用。代理可以被完美地、灾难性地欺骗,但电汇仍然不会发生,这一切都是因为一个简单的确定性检查站在模型输出和外部世界之间,而提议的行动未能通过它。
这只有在行动以结构化方式到达时才有效,这使得结构成为前提。
合同仅因为行动已被类型化而干净地检查approve_invoice(vendor, amount)。如果代理输出散文“请批准Acme发票”,那么必须有东西来解析它,而唯一解析开放语言的东西是另一个LLM,所以不确定性又回来了。这决定了设计。
一个关键行动必须作为类型化工具调用跨越边界,绝不能作为自由文本。当输入不可避免地是自然语言时——例如,一封电子邮件说“给他们汇出余额”——让模型提取结构化值,但绝不让其提取自行授权。模型提议金额;门仍然根据限额、供应商注册和记录系统中的实际余额检查它,而不是电子邮件断言的数字。提取是概率性的,而验证保持确定性。
一些决策是纯判断,没有模式,例如“这封邮件是钓鱼吗?”在这种情况下,模型仍然在循环中。而是通过可逆性和超过阈值的人工审查来约束后果。合同保护可参数化的行动,而不可参数化的判断则回退到遏制。
这表明的架构
一旦你接受安全存在于行动层,三个设计承诺随之而来,它们几乎直接映射到多年前硬化分布式系统的原则。
代理的最小权限,范围限定到行动而非代理。天真的版本假设你可以预测代理会做什么并相应配置。对于专用代理,你可以:一个只做摘要的代理没有理由持有能转移资金的凭证。但人们实际使用的代理是通用的。在单个会话中,我可能要求编码代理摘要文件、编写代码、执行代码和查询公司数据——四个任务,四个风险配置,没有一个事先枚举。静态最小权限在单一身份跨越该范围时崩溃。
修复方法是使权限成为行动的属性,而非代理的属性。代理不通过常驻授权持有任何危险能力;它请求每个行动的窄的、瞬时的提升,由同一确定性门批准或拒绝。读取文档自动批准;查询仓库则不。危险凭证仅在行动被允许的瞬间存在,然后蒸发。一个警告:这管辖代理可以触及什么,但不管辖它编写的代码随后做什么。执行代码可以作为能力被门控,但执行的内容仍然需要遏制、沙箱和出口控制,因为生成性是与访问不同的问题。
机器身份的零信任。代理的每个行动都应被认证和授权,就像来自不受信任的参与者,因为功能上,它可能正在按照攻击者的指令行动。代理的激增扩大了攻击面,速度超过大多数身份系统设计能处理的速度,将代理流量视为内在可信因为它源自你自己的系统正是那个错误。
边界的能力合同。每个关键行动都通过一个确定性门,编码了什么被允许、美元限额、速率限制、白名单目的地、强制人工审查阈值。合同是版本控制的、可审计的,完全存在于模型之外。
常态偏差的陷阱
更安静的组织危险是将不安全的代理连接到真实系统并观察没有坏事发生而缓慢积累的虚假信心……暂时如此。研究人员多年警告间接注入,但大多数部署都幸免了。每个平安无事的日子使下一个风险连接感觉更安全。这是常态偏差。每个最终灾难性失败的系统在失败前都感觉同样:正常、正常、正常,直到它不再正常。
将经受住即将到来的代理事件浪潮的团队不是那些拥有最聪明输入过滤器的团队。他们是那些从一开始就假设妥协并无论如何构建了枯燥执行层的团队,那些决定代理的自主权恰好终止于它试图做不可逆转事情的点上的团队。
从哪里开始
你不需要重新架构一切。从盘点你的代理可以采取的行动开始,并按爆炸半径排序:如果这个行动在不该触发时触发了,最坏情况是什么?对于每个高爆炸半径行动,编写一个确定性合同来门控它,并在你可以向风险团队辩护的阈值之上放置一个人工循环。然后,而且只有然后,继续硬化你的输入。
提示注入不会在输入层被解决,因为它不可能。但它可以在行动层变得可生存,那里确定性代码拥有最终决定权。模型的工作是有用。你的架构的工作是确保当模型失败——或者更糟,当它被用来对付你时——失败在门处停止。