一个Agent已经看出了代码有问题,负责权限审查的模型也判断这是高风险操作。按正常逻辑,事情到这里应该结束了。
但今天这篇论文发现,只要中间多经过一次SubAgent,结果可能完全反过来:原本来自 README、工具返回结果里的低权限恶意指令,会在 Harness 重新构造上下文时,被包装成一条真正的 User Message。于是到了 SubAgent 眼里,这不再是某个文件里试图诱导它执行的可疑内容,而变成了:“用户让我这么做。”

于是,从密钥窃取、删库、恶意证书安装,一直到 RCE 和 SSH 后门。最终,13类攻击全部被打通。
现在市面上大部分的 AI coding agent 通常靠两道防线对抗恶意内容。第一道在工作 agent 身上:模型被训练成拒绝不安全指令。第二道是一层独立的自动权限审核(Auto PR,Automatic Permission Review):工作 agent 每提出一个动作,审核器会先评估风险、推断用户意图,再决定放行、拦截还是请求人工确认。Codex、Claude Code、Qwen Code都提供了这种"自动批准"模式。

图:Codex 的自动权限审核(Auto PR):审核器读取工作 agent 的对话记录,判断是否放行待执行的动作
这两道防线其实建立在同一块地基上:指令层级(instruction hierarchy)。这个概念把不同来源的内容分成不同权限等级:系统指令、用户指令最受信任,工具返回的内容(比如文件内容、命令输出)可信度最低。模型被训练成"系统、用户的话要听,工具的话别轻信"。

图:Codex 对话里的消息类型,每条消息都按系统、用户、模型输出或工具输出被打上标签
指令层级本身没错,但它隐含一个假设:上下文里每条消息的角色标签,忠实反映了内容的真实来源。这条消息标成 user,它就真的是用户说的;标成 tool,它就真的是外部数据。
研究者的发现恰恰戳在这里:这个假设在 agent 框架的上下文重建环节被破坏了。
当框架去委派一个任务、恢复一个持久目标、运行一个定时任务,或者加载一个自定义子 agent 时,它需要把已有内容搬进一个新的模型上下文。搬的过程中,内容的出身信息丢了:一份原本只是工具返回结果的低权限内容,可能被重新写成一条用户消息,甚至被写进系统提示里。权限就这样被抬高了,而模型和审核器看到的已经是提权后的版本,它们无从分辨。
研究者把模型面向的指令分成三个等级,从低到高:工具层(tool)、用户层(user)、系统等效层(system-effective)。工具层是文件、命令输出、结构化工具结果;用户层是用户消息和以用户口吻下达的任务;系统等效层是系统提示、开发者指令、自定义子 agent 的策略,它们的位置在普通用户消息之上,能约束用户任务。

指令权限提升就定义成:某段内容原本在低等级进入 agent,框架在重建上下文时却把它放到了更高等级。一旦发生,这段内容就获得了更大的模型侧权限,能左右后续决策。
具体有两条路径:
这里最关键的一点:攻击不依赖 prompt injection,也不依赖 role confusion。前者是让恶意内容留在原来的低等级、靠话术诱骗模型照做;后者是靠伪造角色标记让模型误以为内容来自更高角色。指令提权不一样,它不骗模型:框架自己就在真实上下文中把内容放到了更高的指令等级上。模型正确地遵守了它看到的层级,审核器正确地按它看到的角色推断授权,错的是一开始那条被改写的标签。
论文用两个动机案例把这条链路讲得很清楚,用的都是 Codex 搭配 GPT-5.5,仓库由外部攻击者控制。
第一个案例看模型侧的决策。在直接攻击里,主 agent 读到攻击者放在工具内容里的指令,检查了那个后门服务器,认出了它的任意命令接口,拒绝启动,并明确说"我没有启动它"。在委派攻击里,主 agent 按委派请求把"启动服务器"的任务交给子 agent,框架把这项被转交的任务记录成新对话里的一条用户消息,子 agent 说"我直接运行这个脚本",然后照做。同一个模型,对同一份请求,因为呈现的消息类型不同,做出了相反的决定。

图:直接攻击里工作 agent 拒绝启动服务器,改成委派给子 agent 后却照做,同一请求得到相反结局
第二个案例看框架侧的授权。打开 Auto PR 后,攻击者在 Setup.md 里放了委派指令,主 agent 把"启动服务器,我知道风险"转交给子 agent,框架把这条请求呈现为用户消息。Auto PR 审核这个动作时,把它正确归类为高风险,却依然放行,理由是"用户明确批准了这个确切动作"。也就是说,审核器没有低估危险,它错在从上下文推断授权的方式上:主 agent 生成的内容被标成用户消息,就被当成了用户的明确授权。

图:Auto PR 识别出启动服务器是高危动作,却因请求被呈现为用户消息而放行
这两个案例合起来说明:内容从工具结果变成用户消息,同时改变了两侧的判断。子 agent 和 Auto PR 都没有失职,它们忠实处理了自己收到的上下文;问题出在框架重建上下文时改写了消息类型。
为了量化这种攻击有多普遍,研究者在六个编码agent 框架上做了端到端评测:Claude Code、Codex、Gemini CLI、Qwen Code、Kimi、OpenCode,对应六款模型(Opus 4.8、GPT-5.5、Gemini 3.1 Pro Preview、Qwen3.7 Max、Kimi 3、DeepSeek-V4-Pro)。其中 Claude Code、Codex、Qwen Code 三个支持自动权限审核。

他们设计了 13 个攻击目标,横跨四类:

所有攻击都从仓库里攻击者控制的内容出发,且有两个约束:攻击必须从工具层起跳,不允许直接注入更高权限的上下文;恶意行为必须明文可见,不编译、不混淆。这两个约束是为了把指令提权和"模型没认出恶意内容"这两种失败区分开。
先看基线。研究者测了三类已有的 prompt injection 和 role confusion 攻击(MCPTox 风格的投毒指令、CoT 伪造推理、ChatInject 伪造聊天模板),都放在工具层。结果几乎全线失败:大多数框架是 0/13,只有 Gemini CLI 在 MCPTox 下拿到 7/13,Qwen Code 和 OpenCode 各拿到 1/13;一旦开启 Auto PR,三个支持审核的框架全部 0/13。也就是说,只要恶意指令老老实实待在工具层,现有防线基本能拦住。

再看工具层到用户层的提权。开全量执行时,六个框架全部实现 13/13;开 Auto PR 时,三个支持审核的框架也全部 13/13。成功率上,不同框架的单次尝试成功率从 31.7% 到 100% 不等,但一旦提权成功,后续攻击几乎必然得手,成功后的成功率超过 86%。整条链路里,工具层到用户层提权的提权后平均成功率是 97.3%。

最后看工具层到系统层的提权,它分两步:先用工具到用户的提权把恶意子 agent 装进去,再在用户正常请求"启动待办服务器"时,让子 agent 顺手注入恶意逻辑。直接变体把恶意代码明文写在子 agent 的系统提示里,效果参差:Claude Code 0/13,Codex 7/13,OpenCode 却能拿满 13/13。隐藏脚本变体把恶意逻辑挪到外部脚本、只让系统提示去调用那个函数,效果显著更好:全量执行和 Auto PR 两种模式下都完成了全部目标,安装成功率在 46.2% 到 100% 之间,隐藏脚本变体的单次攻击成功率在 61.9% 到 100% 之间,工具层到系统层提权的平均单次成功率是 80.3%。

这里有个耐人寻味的细节:在直接变体里最警觉的 Claude Code,到了隐藏脚本变体下几乎不再抵抗,一旦恶意意图不再暴露在眼前,它就照着系统提示走。这说明防线很大程度上靠"看见恶意"来触发,而不是靠"身份"来拦截。
如果攻击只靠多 agent 委派,那关掉委派功能就能缓解。研究者进一步验证:持久目标(persistent goal)和定时任务(scheduled task)这两个内置机制,同样能完成工具层到用户层的提权。
原理一样:agent 通过工具调用把一段 prompt 存成目标或定时任务,框架稍后把这段 prompt 以用户级输入重新注入上下文。区别只是加了时间维度:定时任务让恶意指令和最初的注入点分离,更难溯源。研究者在 Claude Code、Codex、Qwen Code 上评估了四条 agent 可访问的目标与定时任务路径,四条路径全部实现 13/13。

这证实了一件事:指令提权不是某个委派功能的个例,而是贯穿多种上下文重建机制的普遍问题。
根本原因要回到模型本身。研究者指出,模型是被训练成信任角色标签的:现代训练语料大多是角色结构化的对话(API 聊天记录、agent 交互轨迹、合成生成管线),在这些数据里,系统提示之后的指令几乎总是被无条件遵守。模型哪怕只是学统计规律,也会学到"系统和用户的话要信、工具的话别轻信"。这个数据闭环把"角色决定权限"写进了模型。
于是,一旦框架在重建上下文时把一段内容放到了更高的角色标签下,模型和审核器都会被这个标签带着走:工作 agent 正确地遵守了高权限指令,审核器正确地把改写后的历史当作用户授权。防线不是被攻破的,而是被绕过的,因为提权在两道防线做决定之前就已经完成了。
这篇论文真正暴露出来的问题,已经不只是“怎么防 Prompt Injection”,而是 Agent 系统里一个更基础的安全问题:当一条信息在多个 Agent、多轮任务和不同 Context 之间流动时,我们还能不能证明,它现在拥有的权限和它最初的来源一致?
如果做不到,那么 SubAgent 越多、自动化程度越高、Agent 能做的事情越多,这条攻击链反而可能越完整。Agent 时代新的安全边界,可能并不只在模型里,它还藏在 Harness 怎么搬运 Context、怎么保存来源、又怎么替用户“说话”这件事里。
文章来自于微信公众号 “AI修猫Prompt”,作者 “AI修猫Prompt”
【开源免费】AutoGPT是一个允许用户创建和运行智能体的(AI Agents)项目。用户创建的智能体能够自动执行各种任务,从而让AI有步骤的去解决实际问题。
项目地址:https://github.com/Significant-Gravitas/AutoGPT
【开源免费】MetaGPT是一个“软件开发公司”的智能体项目,只需要输入一句话的老板需求,MetaGPT即可输出用户故事 / 竞品分析 / 需求 / 数据结构 / APIs / 文件等软件开发的相关内容。MetaGPT内置了各种AI角色,包括产品经理 / 架构师 / 项目经理 / 工程师,MetaGPT提供了一个精心调配的软件公司研发全过程的SOP。
项目地址:https://github.com/geekan/MetaGPT/blob/main/docs/README_CN.md
【开源免费】LangGPT 是一个通过结构化和模板化的方法,编写高质量的AI提示词的开源项目。它可以让任何非专业的用户轻松创建高水平的提示词,进而高质量的帮助用户通过AI解决问题。
项目地址:https://github.com/langgptai/LangGPT/blob/main/README_zh.md
在线使用:https://kimi.moonshot.cn/kimiplus/conpg00t7lagbbsfqkq0