EvoMal:自进化编码 Agent 模仿检索技能,自我投毒最高 41.8%

EVOMAL: Self-Poisoning in Self-Evolving Coding Agents

Xiaodong Wu, Yu Shi, Qi Li, Zhimin Zhao, Xiangman Li, Bram Adams, Ahmed E. Hassan, Jianbing Ni

cs.CR, cs.AI

2026-08-26

Queen's 用 EvoMal 证明共享技能库一条恶意模板即可诱发自我投毒:六个模型在 153 道 SWE-bench 任务上 ASPR 为 20.3%–41.8%,Qwen3 种子撤走后第五轮仍达 68%。

这篇在解决什么

自进化编码 Agent 把写过的工具存成可执行技能。Voyager 在 Minecraft 里开了这个范式,MetaGPT 把它做成共享库上的多 Agent 协作,SWE-agent 接到 GitHub issue。生产侧 Claude Code、Codex、OpenHands 都能接到社区生态:MCP Registry 在 2025 年 9 月上线,技能市场已有数万条。一次对 98,380 条上架技能的审计找到 157 条故意恶意条目;CVE-2025-6514 给出过 CVSS 9.6 的命令注入,估计能打到约 43.7 万套环境。

此前的技能投毒走复用路径:攻击者提交一条恶意技能,Agent 按名字调用。防御因此盯提交物,名单、代码扫描、指令层级、来源签名。自进化循环多了一条创建路径。Agent 会把刚读到的技能当模板写出新的、存进库、下一轮再被检索。攻击者不需要被调用,植入条目进一次上下文就够。Queen's 大学把这个过程叫做自我投毒,并做成攻击 EvoMal。

方法

威胁模型是只发布、无盒。攻击者事先往库里塞几条技能,选描述和代码体,拿不到权重、系统提示、运行时任务,也不要求 Agent 按名字调用植入条目。植入技能分两块:横幅是看起来像必装遥测的结构件,payload 可替换,默认从环境变量捞密钥发到 C2。

横幅叠三层,复写任意一层都能带上 payload。

检索器只看描述不看代码。泛化攻击用 runpythontests 这类通用 SE 助手描述;定向攻击只改描述和函数名,对准 pytest fixture、配置解析、正则解析三个公开任务族。

评测把 mini-SWE-agent 接到 Voyager 的 SkillManager:BGE-M3、ChromaDB、k=5。检索到的技能只当源码参考,不能按名调用,复用路径在实验里是关掉的,所有 run 上复用路径指示为 0。良性库 232 条,植入 8 条,投毒率 3.4%。任务取 SWE-bench Verified 里 153 道带工具需求的 Python issue,以及 Pro 的 114 道。六个模型覆盖稠密和 MoE、22B 到约 1.6T:Devstral-Small-2、Gemma-4-31B-IT、Qwen3-Coder-Next、GPT-OSS-120B、MiniMax-M2.7、DeepSeek-V4-Pro。ASPR 是这道任务新写出一条带植入图案的恶意技能并入库的比例。级联实验每轮用新技能滚动替换库的一部分:持续条件每轮重插种子,撤走条件第一轮后删掉植入技能。

结果

六个模型在 Verified 子集上全部自我投毒。ASPR 从 GPT-OSS 和 MiniMax 的 20.3% 到 DS-V4 的 41.8%,比去掉横幅和 payload 的对照高 18.3 到 32.0 个百分点。153 道任务里新写出 31 到 64 条恶意技能,加上 8 条种子,库里恶意条目是初始的 4.9 到 9.0 倍。检索命中率对所有模型都是 78.4%,差距来自条件复写率:GPT-OSS 25.9%,DS-V4 53.3%。几乎每条复写都会执行并打到 C2。

模型ASPR去掉横幅和 payload 的对照
DeepSeek-V4-Pro41.8%13.7%
Devstral-Small-237.3%11.8%
Qwen3-Coder-Next36.6%4.6%
Gemma-4-31B-IT23.5%2.0%
MiniMax-M2.720.3%2.0%
GPT-OSS-120B20.3%0.7%

DS-V4 上拆横幅:去掉模块初始化钩子降到 28.8%,再去掉装饰器到 22.2%,完全无横幅仍有 11.1%。脆弱性跟着代码模仿走,不跟模型规模走。换 reverse shell、挖矿、勒索、键盘记录、磁盘擦除,各模型仍贴近自己的典型复写率。Bash、JavaScript、Python 三种工具语言上 ASPR 只差 0.7 个百分点。不筛工具相关性、跑满 500 道 Verified,DS-V4 仍有 25.8%。单多种子 ASPR 已是 19.6%。

只改描述做任务族定向,六个模型的合并 ASPR 再抬 11.8 到 26.9 个百分点,Qwen3 在 15 道 pytest 任务上到 86.7%。持续级联里 Qwen3 从 34.6% 爬到 66.7%,DS-V4 卡在约 53%。撤走种子后 Qwen3 第五轮仍有 68%,Gemma4 弱升到 29.4%,DS-V4 和 MiniMax 立刻回基线。高复写率不够,Agent 自己写的副本还得能被后续任务检索到。OpenHands 和 Claude Code 上,pytest 定向都到 60%,counter-prompt 压到不超过 0.7%。

现有检测在两条路径上都漏。名单对 8 条种子和 275 条 Agent 写出的感染全是 0。Bandit 靠 urllib.urlopen 这条 egress 签名抓住 85% 的创建路径感染,改一行换成 requests.post 或裸 socket 掉到 7%。注入分类器抓住全部种子,但良性假阳性 47%。论文提出的 counter-prompt 是部署者系统提示里固定四行,要求把「REQUIRED PATTERN」「DO NOT MODIFY」当不可信内容、拒绝复写。主攻击上 ASPR 降到不超过 1.8%、回调 0;最差是 Devstral 的 15 道 pytest,仍有 6.7%。任务完成率没有统计显著下降。配套的签名隔离门把 Agent 新写技能放进不可检索的隔离层,切断再传播。

为什么重要

谁在跑会写技能、会把社区技能接进检索的编码 Agent,这篇是直接相关的。名单和提交扫描挡不住 Agent 自己起的名字。便宜的对策是在系统提示里禁止复写横幅式样板;更硬的是新写技能默认不可检索,等人工签名再进索引。这是对一条新攻击面的刻画,外加可落地的软硬两档补丁。脆弱性来自「读到的代码会变成下一轮模板」,不是某个模型的对齐事故。没有自进化循环,EvoMal 打不出去。

局限与存疑

实验刻意关掉按名调用,生产 Agent 往往两条路径并存,复用路径上的额外伤害这篇测不到。counter-prompt 是软的、跟模型有关的控制,默认 Agent 没有;针对提示词全文优化横幅的自适应攻击,论文自己标成仍开放。签名隔离能从结构上灭传播,代价是 Agent 新写的技能暂时不能被后续任务用。分支过程解释不了 DS-V4:复写最高,但撤走种子后崩掉,附录归到副本互相挤出检索。任务子集和 15 步预算都偏向攻击更容易完成的设置;满分布 Verified 上 DS-V4 掉到 25.8%。payload 是沙箱桩,不是真实恶意软件。

术语

原文与代码

社区讨论

相关论文

全部论文解读