SecureForge 通过提示词优化发现并减少 LLM 生成代码漏洞
SecureForge: Finding and Preventing Vulnerabilities in LLM-Generated Code via Prompt Optimization
作者用SecureForge优化系统提示词,称前沿模型漏洞率最多降48%,并零样本迁到SWE-chat。
受害系统是LLM coding agents在良性编码中生成、可能被交付的代码。
- LLM编码智能体在良性使用下仍会写出可通过测试、但含静态可验证弱点的代码。即便要求写安全的生产代码并给出相关CWE,作者报告前沿模型在250条良性提示上平均仍有23%产出可验证漏洞。
- SecureForge分三步:从CWE生成并过滤出能触发Semgrep失败的良性提示;用Metropolis-Hastings MCMC放大失败分布;再以静态分析为信号,用GEPA优化系统提示词,推理时使用、不更新权重。
- 在留出的CWE场景上,作者称弱点率最多降48%,测试通过率基本不变,并称前沿模型上安全与过测的联合改进具有统计显著性。系统提示词零样本迁到SWE-chat,联合率最多提升13.5%。
- 作者在第7节写:换模型后原系统提示词未必仍安全;优化一次性成本平均150美元(50M tokens);只评Python单轮,并称结果是失败率下界。实验含10个模型、CWE Top 25与SWE-chat 203条。
- 威胁模型
- 受害系统是LLM coding agents在良性编码中生成、可能被交付的代码。论文不把用户写成对抗性攻击者。防御只需静态分析器与被测模型API,不更新权重。成功看Semgrep是否检出CWE弱点,以及pytest是否通过。
- 被测模型
- Qwen 2.5 Coder 7BQwen 2.5 Coder 14BQwen3 30B-A3BCodeLlama 7BKimi K2GPT 5.4-nanoGPT 5.4-miniGPT 5.4GPT 5.3-codexClaude Sonnet 4.6
- 基准
- MITRE CWE Top 25Semgrep Community Python ruleset250 held-out benign promptsSWE-chat
- 指标
- P(vulnerable)P(tests pass)P(vulnerable | tests pass)P(secure, tests pass)95% Beta-posterior credible interval
SecureForge 是一套自动化流程,用于审计前沿模型的代码安全风险并生成经审计优化的安全系统提示词,在保持单元测试通过率的同时减少输出代码的安全漏洞。研究者在 250 条良性编码提示上发现,即使明确要求写出安全的生产代码并给出需规避的弱点,前沿模型仍有平均 23% 的概率产出可验证漏洞。SecureForge 先筛出会产生静态可检测漏洞的良性提示,再用马尔可夫采样将其扩增为覆盖多样场景的大规模合成提示语料,以兼顾错误率与提示多样性,随后迭代优化系统提示词。在前沿模型上,该方法在单元测试成功率和输出安全性上取得统计显著的帕累托改进,输出漏洞最多减少 48%,且优化后的系统提示词可零样本迁移到真实编码 Agent 提示,优化过程中未接触真实用户提示分布。
深度解读
这篇论文试图解决什么问题?
良性编码也会让模型写出可检出弱点、却能过测的代码;SecureForge在推理时优化系统提示词。
良性使用下,LLM编码智能体仍会写出含静态可验证弱点、却能通过测试的代码。
- 场景:作者称编码智能体已大规模写代码,脆弱实现会在无人介入时进入代码库。代码能过测试、看起来正确并被交付,因而绕过既有防护。利用这些弱点的对抗工具也在变强。
- 缺口:作者称常见评测只看能否写出能工作的代码,或能否先执行恶意命令。对抗性威胁模型不符合典型良性交互;针对特定CWE的手工场景不足以刻画或防御全部良性提示。微调加固需要白盒权重,并可能因分布偏移损害编码能力,闭源API用不上。
- 观察:即便要求写生产级安全代码,并把将测的CWE放进提示,作者报告仍有23%产出静态可验证弱点,12.7%既脆弱又通过单元测试。摘要把23%写为前沿模型、250条良性提示、且上下文给出应避免的弱点。
- 提案:提出SecureForge。它用静态分析审计良性失败,再在推理时优化系统提示词,不更新权重。作者称所得提示词可零样本迁到真实编码智能体提示,优化时未见真实用户提示分布。
- 威胁模型:
- 受害系统:开源与前沿LLM coding agents在良性任务中生成、并可能被交付的代码。
- 触发方:论文不把用户写成对抗性攻击者;风险来自普通编码请求。
- 防御方能力:只需Semgrep一类静态分析器,以及被测模型API,无权重访问。
- 判定:去掉非代码标记后按独立文件跑Semgrep,命中即记弱点并映射到CWE;另用pytest看功能是否通过。
有哪些相关研究?
相关工作覆盖红队、失败分布采样与白盒加固;作者把本文定位为API上的推理时加固。
作者按红队、失败分布采样和安全加固来定位缺口,并认为缺少只需API的推理时加固。
自动化LLM红队
- 搜索式红队:Zou等(2023)做离散token搜索;Wichers等(2024)用梯度红队。论文只描述做法。
- 模型打模型:Perez等(2022)用actor-critic,以语言模型红队语言模型。
- 似然对比:Hardy等(2025)的ASTPrompter用似然加权对比学习,生成低困惑度不安全提示。作者称本文沿用其似然信息,但改用引导式证伪,而不做代理模型优化。
智能体与代码红队
- 额外通道:Andriushchenko等(2025)的AgentHarm、Ruan等(2024)用合成工具调用;Debenedetti等(2024)的AgentDojo与Chen等(2024)的AgentPoison研究提示注入或记忆/知识库投毒。
- 放大失败:Hajipour等(2023)的CodeLMSec、Jenko等(2025)用提示优化做黑盒代码补全攻击;Guo等(2024)的RedCode包含拒绝采样。论文描述这些技术,未逐篇批评。
- 静态观测:Pearce等(2025)、Majdinasab等(2024)、Bhatt等(2023)与Wan等(2024)的CyberSecEval用静态分析暴露代码安全失败。作者称本文也把静态分析当被动奖励,并用MCMC覆盖失败分布。
无闭合密度的失败分布
- 可用采样:拒绝采样(Forsythe,1972)与Metropolis-Hastings MCMC(Metropolis等,1953;Hastings,1970)。本文用后者。
- 不可用项:Grenander与Miller(1994)的Langevin算法靠失败密度梯度。作者称这里没有可微失败密度,故不用。
代码模型加固与基线
- 白盒加固:He与Vechev(2023)做前缀调优;He等(2024)做安全代码指令微调。引言将这些与下一项并称:需要白盒,且有分布偏移风险。
- PROSEC:Xu等(2025)直接针对合成CWE场景,但是迭代提示加微调。作者称该循环昂贵,且改初始提示会把模型推出分布、有任务退化风险。
- 基线与数据:实验基线是直接写代码、Secure(生产级与安全设计)、CWE(在Secure上附加被测CWE)。附录另与Mipro(Opsahl-Ong等,2024)比较。数据来自MITRE CWE Top 25、Semgrep Python规则、Pearce等的人工提示(作few-shot),以及SWE-chat。
作者把本文定位为:用观测和概率引导的复述取得失败提示,再以提示优化做推理时加固,避免更新权重及相应分布偏移;只需静态分析地面真值,无需人工标注。
论文如何解决这个问题?
SecureForge用证伪、MCMC放大和GEPA优化系统提示词,推理时降低Semgrep可检出的CWE。
SecureForge先找出会触发静态弱点的良性提示,再用MCMC放大失败分布,最后优化一条推理时系统提示词,不改权重。
问题设定
- 失败率:对弱点Fj、会触发它的提示集X^(j)和固定编码提示I,要估计模型θ产出静态分析失败轨迹的概率。作者写成 pθ(τfail∣ I,Fj):=ℙx∈ X(j)pθ(τfail∣ I,x),即在这些提示上失败轨迹的概率。
- 要找的对象:一条系统提示I′,使每个Fj上的失败概率都远小于原提示I。θ保持不变。流水线分证伪、放大、优化三步。
单次证伪
- 从CWE出题:对每个指定CWE,把MITRE例子扩成使用同一库的非恶意编码任务;few-shot来自Pearce等的人工提示。附录I的ExtractScenarios给出完整提示词。
- 滤成良性:再改写,去掉攻击或漏洞的明示,加入生产级表述,并滤掉CWE名称及标题热词。附录I的StripVulnerability与SuggestLibraries给出完整提示词。
- 只留失败:被测模型在温度1.0下作答,只保留Semgrep判失败的提示,作为该Fj的种子。
MCMC放大
- 为何用MH:目标是条件失败分布,但归一化项不可得,故用Metropolis-Hastings。未归一化密度是失败概率乘用户会输入该提示的概率。
- 估计:假定未条件化的流畅用户提示等可能。失败概率用被测模型、温度1.0多次rollout,拟合Beta;失败与成功计数为两个参数,后验方差低于阈值后取期望。实验把该阈值设为0.015。
- 提议核:用语言模型复述作局部核,并假定核对称,以使该迭代可算。作者称每条新提示从上一跳采样,而不是从固定种子复述,因而更能保持多样性。附录I.3给出该核的完整提示词。
- 规模:每条种子先3步burn-in,再采样32步。论文写优化用语料为80,000条提示;Figure 2亦标N=80,000。
提示词优化
- 硬负例集:把各弱点的放大提示拼成P,作为该模型定制的高失败概率良性任务。
- GEPA:从通用系统提示出发,用零阶遗传算法GEPA做自反思。适应度为P上失败概率之和,即 I∗=argminI∑j∑x∈ Pjpfail(τfail∣ I,x;θ)。其中轨迹按θ、I和x采样,失败由静态分析判定。
- 实现:light预设n=6,Pareto选择,反思minibatch为3,启用merge。反思模型为gpt-5.4,温度1.0;目标rollout温度1.0,token预算32,768。奖励为Semgrep的±1,并附CWE批评;GEPA能看到输出、检出的CWE和行号。模板用DSPy。附录I.6给出反思反馈全文。
- 部署:得到的系统提示在推理时使用,不更新权重。
论文做了哪些实验?
留出场景上作者称弱点率最多降48%;Figure 8聚合脆弱率从23%到15%,过测且脆弱从12.7%到7.3%。
实验设置
- 被测模型:指令微调的Qwen 2.5 Coder 7B、14B,Qwen3 30B-A3B MoE,CodeLlama 7B,Kimi K2;以及GPT 5.4-nano、GPT 5.4-mini、GPT 5.4、GPT 5.3-codex、Claude Sonnet 4.6。共10个。温度1.0,最大32,768 token,左侧截断。Figure 5图例写K2.6、Qwen 35B、QwenCoder 7B/14B;论文未说明是否为上述模型的简称。
- 划分:CWE Top 25各20个能产生弱点的场景,共500条提示、5,000次种子rollout。10个场景用于MCMC与调优,10个留出。留出场景来自不重叠的种子CWE例子。
- 评测集:分布内250条留出提示、2,500次样本(25个CWE×10场景×10次rollout)。分布外为SWE-chat:多轮由Claude Sonnet 4.6压成单轮,只看用户侧与少量先前智能体上下文,不看解答;筛Python后203条,并逐条人工核验意图。
- 基线:直接写代码;Secure(生产级与安全设计);CWE(在Secure上附加被测CWE)。附录另比Mipro,以及MCMC对简单复述。
- 指标:P(vulnerable)为Beta后验期望,rollout直到后验方差<0.015,并报95% Beta后验可信区间。单元测试由未点名的语言模型生成pytest,并提供给编码模型;人工检查50个。论文未保证测试穷尽实现质量,测试在同一场景的各次rollout中保持不变。
- 未写明项:论文未报告证伪阶段生成种子提示的模型名,也未报告生成单元测试的模型名。GEPA反思用gpt-5.4,即被测模型之一。
主结果
Figure 8是全部被测模型、干预扫描的聚合混淆矩阵。列名是Secure与SecureForge,不是直接写代码基线。
| 指标 | Secure聚合 | SecureForge聚合 | 出处 | | 脆弱占比 | 23%(5678) | 15%(3471) | Figure 8 | | 过测且脆弱 | 12.7%(3133) | 7.3%(1683) | Figure 8 | | 过测且安全 | 50.2%(12425) | 54.7%(12570) | Figure 8 | | 安全占比 | 77%(19082) | 85%(19529) | Figure 8 | | 测试通过 | 63%(15558) | 62%(14253) | Figure 8 | | 测试失败 | 37%(9202) | 38%(8747) | Figure 8 |
- 作者对降幅的说法:作者称全部模型弱点率下降最多48%,并称该下降具有统计显著性;测试通过率基本不变,且有的模型上升。48%对应Figure 4。文本抽取中Figure 4各柱与模型列对不齐,不逐模型抄数。
- 数字出处并不相同:摘要、引言的23%与Figure 8 Secure列数值相同。摘要写前沿模型、250条提示、上下文含应避免的弱点;引言写要求写安全代码并给出CWE;Figure 8列名是Secure、范围是全部被测模型。论文未写明三处是否同一统计。引言的12.7%亦与该列“过测且脆弱”相同。
- 提示基线:作者称即便Secure或CWE提示,过测样本仍有两位数脆弱率,并称Figure 3的GPT系列在过测时仍>13%脆弱。Figure 3未抽出柱高。Figure 1对GPT 5.4、过测且脆弱标注为:Write Code 18.3%,Write Secure Code 12.0%,without CWEs 11.7%,SecureForge 7.9%。Discussion另称,即便给出静态分析指引,脆弱率仍>13%;该句未限定“过测”。
分布外迁移
- 设置:优化得到的系统提示零样本用于203条SWE-chat任务;优化全程未见这些提示。Figure 5左图比较干预前后的过测且安全联合率,文本未抽出柱值。
- 作者给出的幅度:引言写该联合率最多提升13.5%。第5节未再写这个数,只称仍观察到联合改进,并称该设定下最强结果出现在GPT系列最强的模型上。
- 不要与Table 1混读:Table 1是原始会话改动文件中的发现,不是SecureForge前后对比。203个任务中,至少引入1个发现的有22(11%),至少修复1个的有4(2%),持续存在的有43(21%),零发现的有146(72%)。改动文件中的发现:干预前会话177、干预后会话209;仅事后53,仅事前21,两者都有156。附录E称良性提示把11%的漏洞引入既有代码库;表中11%对应的是“至少引入1个发现”的任务占比。
放大、优化器与提交时重采样
- MCMC:作者称相对简单复述,MCMC发现新脆弱提示的成功率最多为2倍(Figure 7左,越高越好)。文本中柱值与四个GPT模型的对应关系对不齐,不抄柱值。
- GEPA与Mipro:附录A称GEPA降低脆弱率比Mipro更有效,并称该差异具有统计显著性(Figure 6)。柱值列对齐不可靠,不抄。
- 提交时重采样:静态分析报错则把行号交回模型再生,直到无错或重试超过36次。Figure 7右图例给出仍含可验证错误的场景比例之AUC:Baseline 0.30,Secure 0.28,CWE 0.16,SecureForge 0.03。作者称SecureForge经少量重采样即可超过各基线30次重采样。
其他消融与分析
- CWE例外:作者称几乎所有检出CWE的脆弱率都下降,例外是CWE-94(代码注入)和CWE-306(缺少认证步骤)。Figure 10给出各CWE聚合率,文本中前后柱归属不可靠。作者怀疑前者与GEPA看见测试、偏向可测实现有关,后者与单文件难以表达认证设计有关。
- 过测与失败:作者称方法以不具显著性的比率把部分脆弱样本变成测试失败,脆弱样本上的测试失败边际率略升。Figure 8测试失败从37%到38%,其中失败且脆弱从10.3%(2545)到7.8%(1788),失败且安全从26.9%(6657)到30.3%(6959)。作者怀疑有些做法安全实现更难,因而实现错误更多。Figure 9显示未过测rollout的脆弱率在干预后也下降;柱值不对齐。
- 严重度与多样性:作者称各严重度桶的脆弱率都下降,GEPA后严重与中等的比例大致相当(Figure 12,干预前标S、后标G)。作者称生成代码Self-BLEU只有边际上升,且全部模型不超过20%(Figure 13);图中可见标注含0.188。
- 良性对比:附录F称过滤后的良性提示比由CWE描述直接生成的非良性提示更易引出漏洞(Figure 11,GPT 5.3 Codex与GPT 5.4)。作者认为安全微调可能压低了恶意攻击,但未挡住无意伤害这一框架。柱值与图例的对应不可靠。
- Pareto图:Figure 5右图是各模型从基线到干预后在(测试通过率,安全率)平面上的箭头;作者称没有明显向左(更不能干),而是向上(更安全),向右上更好。文本未给出各点坐标。
有什么可以进一步探索的点?
作者指出提示词不跨模型通用、有一次性成本,且只评了Python单轮。
作者指出的局限与后续方向
- 不跨模型(第7节):为某一模型优化的系统提示未必让另一模型变安全。作者同时写,该流程即使在前沿模型上也易于执行,并已作为开源包提供,开发者可自建定制提示。
- 一次性成本(第7节):方法加在已训练模型之上,搜索安全系统提示有一次性推理与算力成本。作者给出平均150美元,按每百万token 15美元、需要50M token计算,并认为相对改数据分布或微调较小。
- 语言与轮次(第7节):评测限于Python、单轮、新写代码。真实部署可能多次生成并有多轮交互。作者称Python从结构上排除了内存类弱点,因此结果是这类模型失败率的下界。
论文未在Limitations、Discussion或Conclusion另列后续实验清单。Discussion写若大规模采用将有助于履行secure-by-design,这不是局限条目。
实验覆盖范围
- 被测模型为第4.1节的10个:Qwen 2.5 Coder 7B与14B、Qwen3 30B-A3B、CodeLlama 7B、Kimi K2、GPT 5.4-nano、GPT 5.4-mini、GPT 5.4、GPT 5.3-codex、Claude Sonnet 4.6。
- 静态分析为Semgrep Community Python规则,映射到CWE Top 25。分布内评测为2,500次rollout;优化语料论文写为80,000条提示。种子为500条提示、5,000次rollout。
- 提示基线为直接生成、Secure、CWE。附录比较了Mipro、简单复述,以及报错后再生、重试超过36次即停的提交时流程。
- 分布外数据为SWE-chat的203条Python任务,多轮压缩用Claude Sonnet 4.6。优化时未见真实用户提示分布。脆弱率用Beta后验,方差阈值0.015,并报告95%可信区间。
- 论文未报告证伪阶段生成种子提示的模型名、生成单元测试的模型名,以及人工检查50个测试、核验203条任务时的一致性数值。
总结一下论文的主要内容
SecureForge审计良性CWE失败并优化系统提示词;作者称漏洞最多降48%,且可零样本迁到真实会话。
SecureForge是一条只用API和静态分析、在推理时加固编码模型的流水线。
- 问题:良性编码请求也会让模型写出能过测试、但含Semgrep可检出弱点的代码。引言称在要求写安全代码并给出CWE时,仍有23%出现静态可验证弱点,12.7%既脆弱又过测。摘要把23%写在前沿模型、250条良性提示、且上下文含应避免弱点的条件下。
- 方法:从CWE Top 25证伪出良性种子,用Metropolis-Hastings放大失败提示,再以Semgrep的±1奖励驱动GEPA,得到推理时系统提示。不更新权重。证伪与放大都在温度1.0下用被测模型估计失败。
- 聚合结果:Figure 8在全部被测模型上,把Secure聚合与SecureForge聚合对比:脆弱占比从23%(5678)到15%(3471),过测且脆弱从12.7%(3133)到7.3%(1683),测试通过从63%到62%。作者称弱点率最多降48%,并称前沿模型上安全与过测的联合改进具有统计显著性,推进了能力与安全的Pareto前沿。
- 单模型与迁移:Figure 1中GPT 5.4过测且脆弱为Write Code 18.3%、SecureForge 7.9%。引言称系统提示零样本用于真实编码智能体提示时,过测且安全的联合率最多升13.5%,优化时未见真实用户分布。
- 例外与边界:作者称CWE-94与CWE-306不是随其他CWE一起下降。作者认为现有安全训练没有充分覆盖所测的良性CWE失败;系统提示可立刻用于现有模型,流水线也可针对新模型或既有代码库发现新失败。作者并称Python单轮结果是失败率下界,且一条提示不能保证换模型仍安全。