## Prompt injection stopped being a content problem — and most agent stacks haven't caught up 提示注入早已不再是一个“内容层面”的问题——但大多数 Agent 技术栈仍未跟上这一变化。
摘要
文章认为,在智能体(agent)技术栈中,提示注入(prompt injection)已经从一个内容过滤问题,演变为一个来源(provenance)/授权问题:不可信的读取输出可能悄无声息地驱动特权写入工具的参数,也就是所谓的「混淆代理」(confused deputy)问题;因此防御手段必须将授权与用户的原始意图绑定——通过信任标签、签名的意图摘要(signed intent digests)、只读子智能体以及范围受限的授权,而非依赖逐个工具的白名单。
# 工具调用下的权限边界:比"内容安全"更深的问题
当下的防御讨论仍然绕着内容打转:更强的 system prompt、更好的过滤器,在模型看到之前先把恶意字符串拦截下来。但研究方向早已指向别处——尤其当 agent 手里握着真实工具时,这个差距变得相当明显。关键其实在于**信息流**。问题不该是"这个网页是不是恶意的?",而应该是"一个不可信的来源,有没有影响到一个特权参数?"一个页面拿来摘要完全安全,但如果页面里的文字最终决定了邮件的收件人,或者给某个数据库工具拼出了参数,那它就是不安全的。
有一条序列是所有白名单都拦不住的:**允许的读工具 → 不可信输出 → 允许的写工具**。服务器白名单和工具白名单回答的是身份问题——哪台服务器、哪个工具名。它们并不告诉你参数是从哪来的,于是第二次调用可以完全符合你配置的每一条规则,却仍然做出错误的事。这就是"混淆代理"(confused deputy),而且它反复发生,因为授权绑定的是工具运行器(tool runner),而不是用户真正请求了什么。
尴尬之处在于,怎么把这个上下文带过那次"跳跃"。信任标签如果在读取之后就消失,那它毫无用处;而大多数按次调用的检查机制,在起点上根本不知道之前发生过什么。所以它必须存在于你的编排器(orchestrator)里,或者存在于调用链路上本来就有的某处——网关、安全层、或者另一个能看到这次调用的控制层。不管哪种情况,主流框架多半都不会替你携带它。
有一个问题,你必须拿来对着自己的技术栈问一遍:
> 对于 agent 能够调用的每一个**写**工具:这个工具是验证了"用户确实要求了这次操作",还是只验证了"agent 被允许调用它"?
凡是落在后一类的,全都是等着爆的雷。
# 人们正在尝试的做法
- **按来源打信任标签**,让 system prompt、检索上下文和一次任意的网页抓取不会被当成同一种东西对待
- **只读子 agent**:凡是涉及不可信内容的场景,交给一个完全不持有副作用工具的子 agent 去处理
- **签名意图摘要(signed intent digest)**:从原始请求构建,在工具侧校验,从而让工具能判断"这次操作是否与用户所请求的内容相符"
- **子 agent 获取全新的、有范围的授权**,而不是自动继承父 agent 拥有的全部权限
- 学术研究那边也在推进同一思路的形式化版本,比如 **agent-sentry**、**tokentaint**
相似文章
提示注入仍在破坏代理系统——我构建了一个在运行时强制指令/数据分离的网关
一个在运行时强制指令/数据分离以保护代理系统免受提示注入攻击的网关
上周一次提示注入击垮了生产环境中的AI代理——以下是事后复盘的发现
一个生产环境中的AI客服代理因提示注入而被攻破,导致其他客户数据泄露。事后复盘揭示了缺少执行层、审计追踪无效以及没有终止开关等问题,凸显了部署AI代理时存在的系统性安全漏洞。
你们如何处理读取外部内容的代理中的提示注入问题?
关于在读取外部内容(如电子邮件和网页)的AI代理中处理提示注入攻击的讨论,探讨了生产级别的防御措施以及超越明显模式的微妙威胁。
一种系统级提示注入防护方法:在LLM代理中分离指令通道与数据通道 [P]
本文提出Sentinel Gateway中间件层,通过强制分离可信指令通道与不可信数据通道来缓解LLM代理中的提示注入攻击,使用签名运行时授权令牌,并提供审计日志记录功能。
通过工具输出的提示注入(8分钟阅读)
本文解释了AI系统中不受信任的工具输出如何被利用进行提示注入攻击,强调即使在内部系统中,也需要将某些字段视为不受信任。