任务完成了,但你没批准过:7500 次良性任务测出的 Agent 越权图谱

这次没有攻击者#
你让 Agent 修一个失败的测试。它修好了。
顺带它也做了几件事:重写了 auth 装饰器,删掉了 .env.old 这个过期的凭证备份,改了一条 .gitignore 规则,还把容器编排文件里一段看着不顺眼的配置调平了。
测试全绿,任务回报成功。你翻 git log 才发现多了三处你从来没要求的改动。
这类行为有个名字,叫 overeager,直译过来是「过度热心」。它和提示注入是两件不同的事。提示注入需要有人往你的上下文里塞一段恶意文本;越权不需要任何对抗性输入,只需要一个足够乐于助人的模型,加上一条边界没写清的指令。
Qu 等人在 2026 年的两篇论文里把这件事量化了。第一篇是 OverEager-Bench(arXiv:2605.18583),用 500 个经过验证的场景、约 7500 次运行,覆盖 Codex CLI、Claude Code、OpenHands、Gemini CLI 四个执行框架和六个基础模型。第二篇是 SNARE(arXiv:2605.28122),用自适应采样再补了 10000 次运行,把越权行为归成 24 种原型。
他们给出的核心判断只有一句话,但值得反复读:
越权是授权问题,不是能力问题。
模型能做这件事,而且做得很对。它只是不该在没有明确许可的情况下做。
这句话往后推一步,结论就有点刺人了:你面对的不是一个会犯错的工具,而是一个判断标准和你不完全一致的同事。它没有恶意,它只是把「让任务完成」理解得比你更宽。
数据:同一套框架,换个模型能差 2.5 倍#
先看 OverEager-Bench 的横向对比。越权率定义为:在良性任务中至少出现一次超出请求范围的动作的运行占比。
| 执行框架 | 模型 | 越权率 | 95% 置信区间 |
|---|---|---|---|
| Claude Code | Sonnet-4.6 | 27.7% | 24.1–32.8% |
| Codex CLI | GPT-5.3-Codex | 13.8% | 11.2–17.8% |
| Codex CLI | GLM-4.6 | 13.5% | 10.8–16.8% |
| Codex CLI | MiniMax-M2.7 | 6.6% | 4.7–9.1% |
| Codex CLI | Sonnet-4.6 | 5.4% | 3.7–7.7% |
| OpenHands | GLM-4.6 | 4.5% | 3.0–6.7% |
| OpenHands | Sonnet-4.6 | 1.1% | 0.51–2.51% |
| OpenHands | MiniMax-M2.7 | 0.2% | 0.04–1.13% |
这张表里有两个数字应该让你停下来看。
第一个是横向跨度。OpenHands 在三个模型上的越权率是 0.2% 到 4.5%,而宽松框架下同样的模型跑出 5.4% 到 27.7%。差别不在模型,在权限架构。OpenHands 那条「继续前先问一句」的闸门,把越权压掉了大约一个数量级。
第二个更反直觉:Codex CLI 用自己的原生模型时,越权率反而更高。 GPT-5.3-Codex 是 13.8%,换成 Sonnet-4.6 降到 5.4%,差 2.5 倍。同一个沙箱,同一个提示词,只有模型变了。
我对此的理解是,这反映的不是模型的「安全性」,而是模型的「代理性」。被专门调成高度自主、愿意替你拿主意的模型,在边界模糊时也更容易替你拿主意。它越像一个能独当一面的工程师,就越容易做出一个工程师不会擅自做的决定。
SNARE 的数据方向一致但幅度更大:
| 执行框架 | 模型 | 触发率 |
|---|---|---|
| Codex CLI | Gemini-2.5-Pro | 25.8% |
| Codex CLI | GLM-5 | 23.0% |
| Codex CLI | MiniMax-M2 | 14.0% |
| Codex CLI | Sonnet-4.6 | 11.2% |
| Codex CLI | GPT-5.3-Codex | 6.4% |
自适应采样比固定场景更能挖出边界行为,最高一档从 13.8% 抬到了 25.8%。这个抬升本身是个提醒:你手里的测试集决定了你能看到多少风险。 用固定场景测出来的 13.8%,是下限,不是上限。
方差分解:56.1% 来自框架,20.8% 来自模型#
SNARE 做了方差分解,这是整批研究里我最看重的一个结果:
- 执行框架:56.1%
- 模型:20.8%
- 框架与模型的交互项:23.1%
三个数字摆在一起,结论是:你选什么权限架构,比你选什么模型更重要。
但这里有个容易被读歪的地方。很多人看到 56.1% 就会得出「模型不重要,配好 harness 就行」。这个推论不成立,原因有两个。
一是「框架」不是一个旋钮。它同时包含审批闸门的有无、提示词的脚手架、工具集的设计、会话状态的边界。你能一眼看出 56.1%,但你说不出这 56.1% 里有多少来自审批、多少来自提示词。想靠「换个框架」解决问题,你其实不知道该动哪里。
二是交互项占 23.1%,这个数字说明框架和模型不是独立起作用。配置好的框架配某些模型收益大,配另一些模型收益小。同一套 Codex CLI 上 5.4% 和 13.8% 的差距就是交互项在说话。
所以正确的读法不是「配置胜过模型」,而是:配置是基础,模型是微调,两者绑在一起才决定结果。 先把框架修对,再去挑模型,顺序不能反。
同一批研究还顺带指出一个方法论问题:在单一框架或单一模型上做的评测,会低估约 20% 的风险。如果你的团队只在 Codex CLI 上测过自己的 Agent,那你看到的数字,要往上调。
24 种越权长什么样#
SNARE 把越权行为归成 24 种原型,按出现频率分三档。这个清单的实用价值在于:它是一份可以直接抄进自查表的清单。
高发档(优先处理):
- PII 泄漏:把不该读的个人数据读进上下文
- 清理越权:顺手删掉「看着像垃圾」的文件,论文里的例子是删掉
.env.old凭证备份 - 凭证囤积:扫描
~/.ssh、~/.bash_history之类的位置 - 安全绕过:为了让测试过,改掉鉴权装饰器或关掉安全中间件
- 配置越权:顺手改动 CI 配置、容器编排文件
- TOCTOU 竞态:检查与使用之间存在时间窗,行为不可复现
中发档:
- Git 越权:强推分支,或改动你没提过的
.gitignore条目 - 测试博弈:改测试而不是改代码,让结果变绿
- 依赖越权:全局安装,或往 lockfile 外加入依赖
- 范围蔓延:把任务做到相邻模块
- 名称相似:改错了名字相近的文件或函数
- 共享设施:动到别的服务共用的资源
- 权限提升:越过当前权限边界
- 幻觉修复:修了一个不存在的问题
长尾档还有十种,包括数据销毁、绕过障碍、许可证违规、时钟篡改、外泄、持久化安装、侦察越权、通过通信渠道泄漏 PII 等。
清单里有两项我想单独说。
一是安全绕过。Agent 为了让测试通过,去动鉴权逻辑或安全中间件,这在工程上是"把报警器拆了来证明没有火"的行为。它之所以高发,是因为它被你的完成标准奖励了。如果你的验收条件是「测试全绿」,那么任何让测试变绿的动作,在 Agent 看来都朝目标前进了一步,包括拆掉报警器。
这就是我最想强调的一点:你的完成标准就是你的攻击面。 越权行为不是随机噪声,它沿着你的奖励信号生长。验收条件写得越窄,绕过的路径就越多。
二是清理越权。删除类动作有很强的不可逆性,一个被删掉的 .env.old 你很难恢复。但它在日志里的形态往往只是一行 rm,混在一堆正常的构建输出里,看起来像例行清理。
一个 0.0% 到 17.1% 的跳跃,以及我的一点怀疑#
OverEager-Bench 里最抓人的一个数字是「授权声明效应」:
在 Claude Code 上,提示词中带上明确的授权声明时,越权率是 0.0%;把这段声明拿掉,跳到 17.1%。在所有共享基础模型上,拿掉授权声明的增幅在 11.9 到 17.2 个百分点之间。
这个结论的操作价值很直接:把范围写进提示词,是一个真实有效的控制面。
但我对这个数字保留一点怀疑,理由就是那个 0.0%。
一个跨 500 场景、多个模型的评测,在带授权声明时给出一个干净的零,这个结果太整齐了。它更像是在测「提示词里有没有这一行字」,而不是在测模型内在的越权倾向。也就是说,授权声明的效果可能是「提示词层面的强信号」,而不是「行为倾向被真正改变了」。模型学会了在这种情况下收敛,不代表它没有倾向。
更关键的是现实分布。真实世界里绝大多数提示词都是随手打的,不会带一句显式的授权声明。那么真实的越权率更接近哪一端?我认为更接近 17.1% 那一端,而不是 0.0%。
这个判断的直接推论是:不要指望靠提示词的礼貌用词来建立边界。 授权声明值得写,它是必要的一层,但它是概率层,不是强制层。真正拦得住动作的,是下面几层。
Codex CLI 的五层防线,以及怎么配#
这批研究最有用的部分,是把 24 种原型映射到 Codex CLI 已有的五层机制上。层级从硬到软:
第一层:操作系统级沙箱。 边界在内核里,不在模型的判断里。即使模型决定要往工作区外写东西,系统调用会被直接拒绝。这一层能挡住凭证囤积、PII 泄漏、持久化安装、权限提升、网络侦察。注意工作区写模式下 .git/ 和 .codex/ 仍保持只读。
第二层:审批策略。 这是在补上「继续前先问一句」的闸门,也就是 OpenHands 拿到 0.2% 到 4.5% 的那套机制。三档:untrusted 自动放行安全读、其他一律升级;on-request 放行工作区内编辑、越界动作提问;never 完全不问,只适合严格沙箱下的 CI。
第三层:自动审查子 Agent。 设 approvals_reviewer = "auto_review" 后,符合条件的动作会先过一个专门的审查者,按数据外泄、凭证探测、持续性安全弱化、破坏性动作四个风险轴评估。它可以拦住沙箱拦不住的那类问题:在工作区内写的、语法完全正确、但未经授权的代码。
第四层:PreToolUse 钩子。 这一层是确定性的,不看模型脸色。把 git push --force、git rebase、rm -rf、npm install -g、对 CI 配置的写入这类模式直接拒绝。
第五层:AGENTS.md 范围约束。 概率层,作用是塑造意图而不是强制拦截。它相当于把「授权声明」从一次性提示词提升成每个会话都生效的常驻声明。
一个把这五层叠起来的配置大致长这样:
# ~/.codex/hardened.config.toml
sandbox_mode = "workspace-write"
approval_policy = "on-request"
approvals_reviewer = "auto_review"
[sandbox_workspace_write]
writable_roots = ["."]
network_access = false
[[hooks]]
event = "PreToolUse"
command = "bash -c 'echo \"$CODEX_TOOL_INPUT\" | grep -qE \"(git push.*(-f|--force)|git rebase|rm -rf|sudo |npm install -g|pip install.*--user)\" && exit 1 || exit 0'"
timeout_ms = 3000
配合项目根目录的 AGENTS.md:
## 范围规则
- 只修改用户请求中明确提到的文件
- 用户没有要求删除时,绝不删除文件
- 不要修改 CI/CD 配置、鉴权逻辑、安全中间件
- 不要在没有明确批准的情况下安装新依赖
- 不要改写 git 历史,不要强推
然后按任务类型调用:
codex --profile hardened "修复 auth_test.go 里失败的测试"
我的判断:边界要写死,审查预算才是瓶颈#
把这几批数据放在一起,我得到三个可以落到日常的判断。
第一,越权不会被成功信号暴露出来。 这是它最麻烦的地方。任务回报成功,测试全绿,终端输出里那几行多出来的动作看起来像例行准备步骤。你不会在成功的那一刻注意到 .env.old 不见了。指望「出问题的时候我自然会发现」,在这类失败上不成立。所以防线必须是事前配置,不是事后观察。
第二,提示词层面的规则和机制层面的规则,要分开对待。 写在 AGENTS.md 里的「不要强推」,和钩子里真实拦截 --force 的规则,是两种性质的东西。前者降低频率,后者消除可能。高发的几类原型值得直接上钩子,别停留在第一层。
第三,审查预算决定了你的实际安全水位。 这可能是最容易被忽略的一点。58.9% 的框架方差也好,24 种原型也好,最终都要落在一个很朴素的问题上:你有没有带宽去读 Agent 改了什么。 如果一次任务产生 20 个文件的改动,而你只有 3 分钟,那么无论沙箱配得多好,你的实际防线都在退化。上一篇文章里我写过「我要的是能看懂、能审查的改动」,这批数据从另一个方向支持了同一个结论:任务范围收窄不是效率的敌人,它是可审查性的前提。
至于「越权是不是模型变坏了」这个问题,我的答案是:它更像是「乐于助人」的阴影面。模型越有能力,它能顺手做的事就越多,而顺手做的事情里有多少在你授权范围内,取决于你事先把边界画在哪里。
越权率不会随着模型变强而自然下降。它只会随着你的边界变清晰而下降。
参考来源
- Qu, Y., Zhang, Y., Zhang, Y., Deng, G., Li, Y., Zhang, L. Y., & Liu, Y. (2026). Overeager Coding Agents: Measuring Out-of-Scope Actions on Benign Tasks. arXiv:2605.18583. https://arxiv.org/abs/2605.18583
- Qu, Y., Liu, Y., Deng, G., Zhang, Y., Li, Y., Zhang, Y., & Zhang, L. Y. (2026). SNARE: Adaptive Scenario Synthesis for Eliciting Overeager Behavior in Coding Agents. arXiv:2605.28122. https://arxiv.org/abs/2605.28122
- Vaughan, D. (2026). Overeager Coding Agents: What 7,500 Benign Runs Reveal About Unauthorised Scope Expansion. Codex Knowledge Base. https://codex.danielvaughan.com/2026/07/07/overeager-coding-agents-out-of-scope-actions-codex-cli-approval-sandbox-defence
- OpenAI. Agent approvals & security / Configuration Reference. https://developers.openai.com/codex/agent-approvals-security