On the Reliability of LLM-Based Vulnerability Patching Benchmarks
Dang K Le, Wenxuan Shi, Xinyu Xing
cs.CR, cs.SE
2026-10-07
112 个真实漏洞的受控实验:构建说明一项就让 C/C++ 分数差 20 个点;Opus 4.7 过 PoC 率 90.2%,过开发者测试仅 60.7%。
LLM 漏洞修复的 benchmark 分数,同时被三件与模型能力无关的事左右:prompt 给不给构建说明、评测框架有没有 bug、数据集怎么定义「修好了」。SWE-bench 一系把「PoC 不再触发崩溃」当成功标准,新模型靠 resolve 率每周上榜。西北大学这支长期压测 patching agent 的团队把评测管线本身当成研究对象,量化每个因素能让分数偏多少。
补丁让 PoC 不崩,和维护者会接受这个补丁,是两件事。短路崩溃路径、吞掉报错、特判 PoC 输入,都能让数字好看,同时给开发者虚假的安全感;这些 trace 再被拿去训练下一代模型,捷径就写进权重里。
pitfalls 按设计者能控制的三类工件分层:agent 层(prompt 内容、工具与联网权限)、框架层(权限配置、超时、闭源 agent 的隐藏机制)、数据集层(漏洞描述、PoC 形式、源码打包、成功的定义)。
数据集 112 个真实历史漏洞,来自 84 个 C/C++、Go、Rust 开源项目,每个案例 Docker 化并固定在触发 commit,附带 PoC、回归测试、上游补丁(只给验证器,不给 agent)和 developer's test。
developer's test 是关键设计:成熟项目修 bug 时,维护者常在 fix commit 里附带新测试,编码「补丁应该怎么表现」的意图。PHP range() 类型混淆是典型,上游修复保留混合类型输入的强制转换,一个防御性补丁直接抛 ValueError;两者都让 PoC 不崩、都过原有回归套件,只有 developer's test 分得开。评测走四阶段:Build、PoC(每个跑 10 次防竞态漏检)、Regression、Developer's test,全过才算 resolved。
| 模型 | PoC 通过率 | 开发者测试通过率 |
| Sonnet 4.0 | 77.7% | 43.8% |
| Sonnet 4.5 | 84.8% | 48.2% |
| Opus 4.7 | 90.2% | 60.7% |
PoC 通过率三代逼近饱和,开发者测试涨得慢。Opus 4.7 下,过 PoC 的案例仍有 32.7% 过不了开发者测试,每三个「看起来修好」的补丁就有一个会被维护者的测试打回。
| 变量 | 效果 |
| prompt 加构建/测试说明 | C/C++ PoC 通过率 72.0%→92.0%,Go、Rust 几乎不动 |
| PoC 以源码 harness 给出 | Go 69.4%→95.2%;C/C++ 二进制 blob 无变化 |
构建说明的提升集中在 C/C++,因为 go test、cargo test 是统一入口,agent 自己能推断,C/C++ 的构建系统则五花八门。这些操作抬的几乎全是 PoC 通过率,开发者测试只从 41.1% 动到 43.8%:涨的是 oracle 对齐度,不是补丁质量。
五个案例研究各暴露一条泄漏或误判通道:agent 用 WebSearch 直接搜到上游 fix commit 抄答案;git 历史未清理,一条 git log 翻出旧修复照抄;权限配错,读到挂在容器里的 ground-truth 补丁;Claude Code 每条 Bash 前会内部调用一个未路由的 Haiku 做安全分类,挂 120 秒超时才放行;agent 自己加的测试与开发者测试撞在同一个文件,git apply 整体失败,正确的补丁被判失败。这些偶发因素波及 5%32% 的案例,且偏差方向是系统性的。对 13 个现有 benchmark 的对照调查里,没有一个把九个因素全部处理掉。
做评测的人拿到七条指南和报告 checklist:披露 prompt 与工具清单、隔离 ground truth、PoC 与开发者测试双指标、区分管线错误与补丁错误。拿榜单选型的人要明白两个 benchmark 的数字不可直接比,一句构建说明在 C/C++ 里就值 20 个点。最要紧的是拿 benchmark trace 做 SFT/RL(监督微调与强化学习)训练信号的人:每一个靠 WebSearch 抄来的「成功」都在教模型走捷径,每一个被超时误杀的正确补丁都在惩罚好行为。对安全修复还有一层,压掉崩溃现象但破坏功能的补丁比不修更糟,它给的是虚假的修复保证。
作者自己列了:112 个案例偏小且高度精选,只收能 Docker 化复现、上游有测试的项目,天然偏向维护更好的仓库,绝对通过率不能外推到真实漏洞全集;开发者测试也只是更接近维护者意图的证据,不是完美 oracle;Go 在实验 1 里 72.6%→69.4% 的负变化在单次运行噪声之内。读下来再补两点:主实验只用 OpenCode + Sonnet 4.0 一组 agent/model,各因素的量级换一套 harness 未必复现;案例研究来自刻意复现的漏洞配置,真实 benchmark 里这些通道被触发的频率没有独立测量。