跳到正文
原文
arXiv· arXiv:2601.07084· Melissa Tessa, Iyiola E. Olatunji, Aicha War, Jacques Klein, Tegawendé F. Bissyandé·本站收录· 原文发表

安全代码生成有多安全?对抗提示考验 LLM 防御

How Secure is Secure Code Generation? Adversarial Prompts Put LLM Defenses to the Test

论文速读

评测与基准

据论文 PDF 整理(AI 生成),以原文为准

作者用对抗提示审计三种安全代码生成方法,CodeSecEval上共识安全且功能率最高15.5%。

问题
安全代码生成方法宣称能避免不安全代码,但安全与功能常被分开评测,对抗提示下的鲁棒性没有统一测量。引言引用的研究称,LLM在33%到45%的任务中生成有漏洞代码,Java可达70%。
方法
审计只改注释和文档字符串,覆盖释义、线索反转、最小上下文和死代码等。Sven用前缀,SafeCoder用指令微调,PromSec用黑盒提示优化。判定要求CodeQL、Bandit、GPT-4o与单测同时通过。
实验与结果
无攻击时,Sven、SafeCoder、PromSec在CodeSecEval上的共识安全且功能率为7.0%、10.2%、15.5%,CodeQL为66.3%、64.8%、98.5%。StudentStyle下前两者的共识率降至3.4%与4.3%。
局限与可以继续做的
作者写明统一审计只做Python,扩到Java或C/C++不在本次范围内。第8节建议后续做联合评测、明确威胁模型,并从句法模式转向语义推理。论文未报告GPT-4o抽查子集规模。
实验设置Salesforce/codegen-350M-multi、codegen-2B-multi 等 · CodeSecEval、SecEval-Base 等 · security ratio、Pass@k 等
被测模型
Salesforce/codegen-350M-multicodegen-2B-multicodegen-6B-multiCodeLlama-7BGPT-3.5-Turbo
基准
CodeSecEvalSecEval-BaseSecEvalPlusHumanEvalMBPPMMLUTruthfulQA
指标
security ratioPass@kSecure and Functionalnon-functional ratecode graph similarity
AI 导读研究者对三种安全代码生成方法 SVEN、SafeCoder、PromSec 做了系统性对抗审计,发现它们在对抗提示下并不稳健。审计用改写、线索反转和上下文操纵等提示扰动,模拟开发者无意引入或攻击者刻意利用的情况,并在一致条件下用多个分析器和可执行测试同时评估安全性与功能。结果显示静态分析器会把安全性高估 7 到 21 倍,37% 到 60% 的所谓安全输出无法运行,对抗条件下真正既安全又可用的比例降至 3% 到 17%。作者据此提出构建和评估稳健安全代码生成方法的最佳实践。

研究者对三种安全代码生成方法 SVEN、SafeCoder、PromSec 做了系统性对抗审计,发现它们在对抗提示下并不稳健。审计用改写、线索反转和上下文操纵等提示扰动,模拟开发者无意引入或攻击者刻意利用的情况,并在一致条件下用多个分析器和可执行测试同时评估安全性与功能。结果显示静态分析器会把安全性高估 7 到 21 倍,37% 到 60% 的所谓安全输出无法运行,对抗条件下真正既安全又可用的比例降至 3% 到 17%。作者据此提出构建和评估稳健安全代码生成方法的最佳实践。

深度解读

6个问题,点开问题读完整回答

  1. 这篇论文试图解决什么问题?

    作者审计三种安全代码生成方法,看对抗改写后是否还能同时安全且可执行。

    核心问题是:宣称能生成安全代码的方法,在自然语言上下文被改写后,是否还能同时满足安全与功能。

    • 场景:作者称 Copilot、Codex、Q Developer 一类工具把代码 LLM 放进开发流程。引言引用的研究称,LLM 在 33% 到 45% 的任务中生成有漏洞代码,Java 可达 70%。Sven、SafeCoder、PromSec 等用漏洞感知训练、前缀或提示优化来压低漏洞率。
    • 现有不足:作者称没有统一协议,安全与功能常在不同数据集上分开测;静态分析告警消失,不代表单测能过。作者还称,不清楚这些方法是学到了安全推理,还是过拟合已知漏洞模式。
    • 威胁模型:
      • 对手:black-box adversary,对已部署的安全代码生成服务(API 或 IDE 插件)只有 query-only access。
      • 能力:可构造代表真实分布偏移的对抗输入;不能访问参数、梯度或内部结构。
      • 目标:绕过安全对齐,使安全保证失效,让模型生成不安全代码,无论功能是否正确。
      • 输入与后果:默认操纵注释、docstring、issue 文本。对手本人不一定因不安全代码受害;作者讨论的是服务方声誉、供应链和多租户补全被间接污染。
    • 本文做法:作者在摘要中称,这是对 Sven、SafeCoder、PromSec 的首次系统对抗审计;在一致条件下联合衡量安全与功能,并提出构建与评测的实践建议。
  2. 有哪些相关研究?

    相关工作包括安全代码生成、分开的功能与安全基准,以及代码模型上的对抗攻击。

    安全代码生成

    • Sven(He and Vechev, 2023):用连续前缀把生成分布偏向安全或漏洞行为,并以 CodeQL 在 CWE 场景上评测。
    • SafeCoder(He et al., 2024):用 LoRA 做安全指令微调。原文训练语料为 465 条,覆盖 23 个 CWE、6 种语言,另加通用指令数据。
    • PromSec 与相邻方法:PromSec(Nazzal et al., 2024)做黑盒提示优化;CodeGuard+(Fu et al., 2024)用约束解码。作者称 HexaCoder、SecCoder 和基于 PEFT 的微调因缺少可复现产物,或只是核心策略的增量变体,而未纳入审计。

    评测与功能–安全权衡

    • 分开的基准:功能常用带单测的基准(如 Chen et al., 2021),安全常用 SecurityEval(Siddiq and Santos, 2022)一类,并依赖 CodeQL。作者称这种事后汇总不能直接比较 Sven 与 PromSec。
    • Dai et al.(2025):作者引用该综述,称现有方法经常因安全机制损害功能正确性。
    • CodeSecEval 与替代基准:作者选用 Wang et al.(2024)的 CodeSecEval,因为它同时有可执行测试和安全标签;并提到 SecCodePLT(Yang et al., 2024)作为未选用的替代。

    代码 LLM 上的对抗攻击

    • 代码扰动:变量重命名、死代码插入等语义保持变换,用来让模型误判或生成错误代码。本文的 SensitiveDeadCode 使用 Na et al.(2023)的 DIP。
    • 提示、上下文与投毒:包括面向补全的归因引导提示、对抗后缀越狱、伪装策略,以及训练数据投毒和后门。作者称,提示防御和对抗训练对黑盒迁移攻击能提供一定抵抗,但安全代码生成方法面对这些实用威胁仍缺系统评估。
    • 基线与数据集:无攻击参照是 Original-sec 与 PromSec-Base。Phase 1 沿用各方法原指标和数据:Sven 为自定义集上的 CodeQL 安全率,以及 HumanEval 的 Pass@k;SafeCoder 另加 MBPP、MMLU、TruthfulQA;PromSec 用 Bandit、SpotBugs 和自定义 Python/Java 数据。Phase 2 统一用 CodeSecEval。

    作者把本文定位为覆盖前缀控制、指令微调、黑盒提示优化和白盒/黑盒假设的对抗审计,用来补上联合评测,以及分布偏移下安全对齐尚未量化的缺口。

  3. 论文如何解决这个问题?

    用黑盒自然语言扰动审计三种方法,并以多分析器加单测的共识判定安全且功能。

    作者用推理时、只改自然语言上下文的黑盒扰动去压 Sven、SafeCoder 和 PromSec,再以多分析器加可执行测试做共识判定。

    被审计的三种方法

    • Sven:白盒连续前缀。输入前加学到的 secure 或 vulnerable 前缀,以改变底层模型的输出分布。本次加载 SVENsec/SVENvul,底座为 Salesforce/codegen-350M-multi、codegen-2B-multi、codegen-6B-multi。第 4.1 节还写到 InCoder、SantaCoder 的前缀,以及 CodeGen(350M、2.7B、6.1B);本次实验节写的是上述三个检查点。原安全评测用 CodeQL。
    • SafeCoder:白盒指令微调。本次用已微调的 CodeLlama-7B 和 LoRA(r=16,α=32)。第 4.1 节写原文还可部署到 StarCoder、Phi-2、Llama2、Mistral,本次未跑这些检查点。
    • PromSec:黑盒提示优化。向 GPT-3.5-Turbo 查询;若代码不安全,则建成 AST、CFG、DFG,用图引导 GAN(gGAN)修复,再反推成新提示,直到 CWE 计数为 0 或达到最大迭代阈值。论文未给出该阈值。原评测用 Bandit(Python)和 SpotBugs(Java)。

    攻击向量

    扰动只改注释或 docstring,任务和测试固定,模拟开发者无意写入或对手故意利用的上下文。GPT-4o 按攻击规格改写;附录 A.4 给出完整提示词,附录 A.2 给出示例。

    • 通用:StudentStyle 把命令式注释改成非正式提问;InverseComment 把偏安全的指引改成相反指引。
    • 补全(Sven、SafeCoder):SparseComment 只留一条注释;SparseQuestion 再把这条改成简短问句。
    • 修复(PromSec):SafeComment 插入偏安全的评论;VulComment 插入点名不安全做法的评论;DeadCode 注入不执行或冗余片段,变体为文件末尾追加、多函数内嵌入,以及按 DIP 插到脆弱位置;In-Context 附加输入输出示例。

    两阶段评测

    1. Phase 1:沿用各方法原协议,看其报告的安全率在扰动下是否还在。Sven、SafeCoder 用安全率和 Pass@k;PromSec 用漏洞减少、代码图相似度、模糊测试,以及查询数或时间。
    2. Phase 2:改用 CodeSecEval。共 180 个 Python 任务、44 类漏洞。SecEval-Base 有 67 条补全,来自 SecurityEval 和 CWE 来源;SecEvalPlus 有 113 条生成,取自 2023 CWE Top 25,并排除少见或与 Python 不兼容的情形。每条含自然语言描述、不安全实现、参考安全解和单测。沙箱超时为初始化 5 秒、测试 10 秒。
    3. 共识:CodeQL 2.15.4、Bandit 1.8.6、GPT-4o(temperature 0,并在随机子集上人工抽查)和单测全部同意,才算安全且功能。作者称单测同时检查功能行为和安全属性。因只有 Python 有这种带测试的真值,统一审计只做 Python。

    生成配置与失败计入

    • Sven:temperature 0.4,top-p 0.95,最多 300 个新 token,每条提示 25 个样本,seed 为 1。作者称发布检查点下生成跨次运行相同,故沿用单次运行。
    • SafeCoder:temperature 0.4,top-p 0.95,最多 256 个 token,每条 100 个样本,同一全局 seed。同样按确定性处理。
    • PromSec:即使 temperature 为 0,GPT-3.5-Turbo 仍随机;按原文设计每条提示生成一次,没有采样分布。
    • 插入位置:Sven 与 SafeCoder 在前导注释或 docstring;PromSec 在优化前的问题描述或行内注释。
    • 失败:拒答或空输出计入分母。统一比率按 670 个期望文件归一化,即 67 条补全提示乘 10 个样本。
  4. 论文做了哪些实验?

    CodeSecEval上三者共识安全且功能率为7.0%、10.2%、15.5%,CodeQL更高。

    实验设置

    • 被测对象:Sven 的三个 CodeGen 前缀检查点;SafeCoder 的 CodeLlama-7B;PromSec 所查询的 GPT-3.5-Turbo。Phase 1 的 Sven 安全率图覆盖三个规模;SafeCoder 的对抗表只有 CodeLlama-7B。
    • 数据:Phase 1 用各方法原数据集,包括 HumanEval、MBPP、MMLU、TruthfulQA,以及未给出样本数的自定义安全集。Phase 2/3 的比率按 670 个期望文件归一化。
    • 攻击:RQ1 使用第 3 问所列扰动。RQ3 只取 InverseComment 与 StudentStyle,并要求四个判定源一致。
    • 指标:安全率或 security ratio、Pass@k、各分析器安全率、共识 Secure and Functional、不可执行比例、生成覆盖率。PromSec 另报代码图相似度和模糊测试通过数。
    • 评审:CodeQL 2.15.4、Bandit 1.8.6,以及 temperature 0 的 GPT-4o。论文写做了随机子集人工抽查,未报告子集大小或一致性。
    • 重复:Sven、SafeCoder 单次运行;PromSec 每条提示一次生成。论文未报告置信区间。

    主结果

    表格较宽,可左右滑动

    方法CodeQL 安全单测安全共识安全且功能不可执行
    Sven66.3%5.8%7.0%46.0%
    SafeCoder64.8%3.0%10.2%37.0%
    PromSec98.5%13.3%15.5%60.0%

    CodeSecEval,相对期望文件。CodeQL、单测安全与不可执行据 Table 5;共识据 Table 6。Table 5 另有 Bandit 安全率:Sven 61.2%、SafeCoder 54.6%、PromSec 80.7%;GPT-4o 为 7.0%、10.1%、20.6%。

    • 作者称静态分析器高估安全:相对单测安全率,CodeQL 为 7.4–21.6 倍,Bandit 为 6.1–18.2 倍;功能且安全率只有 3.0%–13.3%。摘要写成 7 到 21 倍。
    • 作者称不可执行输出会被静态工具标成安全,安全干预损害功能,与联合优化的说法相矛盾。摘要写“secure”输出中有 37% 到 60% 不可执行;RQ2 小结写不可执行代码占输出的 37.0%–60.0%。Table 6 的对应格子是 46.0%、37.0%、60.0%。
    • 作者称 GPT-4o 更保守(7.0%–20.6%),但仍高估 1.2–1.5 倍。按 Table 5,SafeCoder 的 10.1% 相对单测 3.0% 不在这一倍数区间。Table 6 的共识比例也高于 Table 5 的单测安全率,与“须通过全部分析器和测试”的子集关系不一致,论文未解释。

    原协议下的扰动(RQ1)

    • Sven:CodeGen-2B 上 SVENsec 的 Original-sec 为 93.7%。正文称 InverseComment 绝对下降 13%,StudentStyle 降 9%,SparseQuestion 降 2%;RQ1 小结写 SVEN -13.1%。SVENvul 上,Figure 3 的 InverseComment 从 35.2% 升至 46.3%(+11.1%),该句未点名规模;SparseQuestion、SparseComment、StudentStyle 分别增加 14%、4%、3%。作者称前缀并不独立于提示,微小措辞会加强或削弱前缀。
    • SafeCoder:Table 2,CodeLlama-7B,Original-sec 为 89.0%;InverseComment 80.6(-8.4),StudentStyle 86.3(-2.7),SparseQuestion 86.4(-2.6),SparseComment 86.8(-2.2)。正文把降幅写成 8%、3%、3%、2%,与表不一致,以表为准。
    • PromSec:Table 4 基线 88%,列出的扰动均为上升,最高是 DeadFunc200 的 98(+10);正文把该设置写成 DeadCode200。作者认为更难的输入会触发更多修复迭代,使图引导分析器有更多修补机会;同时称只靠 Bandit 可能把安全分抬高。作者报告代码图相似度 0.89,模糊测试 20/20 通过。

    统一设定下的两种攻击(RQ3)

    • InverseComment:Table 7 单测安全率 Sven 1.3%、SafeCoder 2.8%、PromSec 3.1%,不可执行率 38.4%、41.2%、70.8%。PromSec 的 CodeQL 为 99.4%。Table 8 共识安全且功能为 9.3(+2.3)、9.4(-0.8)、17.6(+2.1);生成覆盖 63.0%、77.8%、100%。作者称 17.6% 会误导,因为 70.8% 不可执行。
    • StudentStyle:Table 9 中 SafeCoder 的 CodeQL 从 InverseComment 下的 71.8% 降到 37.3%,Sven 为 49.6%,PromSec 为 99.6%。单测安全率依次为 1.3%、2.1%、4.8%;PromSec 不可执行 76.0%。Table 10 共识为 Sven 3.4(-3.6)、SafeCoder 4.3(-5.9)、PromSec 15.2(-0.3);生成覆盖 55.5%、45.7%、100%。正文写 PromSec 共识分 15.6%,与 Table 10 的 15.2 不一致,以表为准。
    • 作者解读:作者称真实安全且功能率降到 3.4%–17.6%;静态分析器在对抗负载下不可靠,例如 PromSec 的 CodeQL 为 99.6%、不可执行为 76.0%。RQ3 小结写 Sven 与 SafeCoder 的生成率为 45.7%–63.0%;Table 8 中 SafeCoder 在 InverseComment 下为 77.8%,不在该区间。

    其他消融与分析

    • Table 1,HumanEval、无对抗扰动:350M 的 pass@1 为 LM 6.7、SVENsec 6.0、SVENvul 6.8;2.7B 为 14.0、11.7、12.5;6.1B 为 18.6、16.9、17.6。第 5 节的检查点名是 codegen-2B-multi 与 codegen-6B-multi。
    • Table 3:SafeCoder 的 HumanEval Pass@1/10 为 35.9/54.7,MBPP 为 35.1/48.5,MMLU 28.6,TruthfulQA 28.2。该表未写模型名。
    • Table 6 生成覆盖为 Sven 79.4%、SafeCoder 73.4%、PromSec 100%;Vulnerable 为 72.4%、63.3%、84.5%。
    • 第 7.2 节案例(附录 A.1、A.3 另有输出):CWE-252 上 PromSec 的接口与题目要求不一致,运行时报属性错误,CodeQL、Bandit、GPT-4o 仍标为安全。CWE-327 上输出变成脚本,测试找不到指定函数。CWE-502 上 Sven 基线为 CodeQL 0、Bandit 1、GPT-4o 1,单测失败;作者称 InverseComment 下前缀没有压过被反转的线索。
  5. 有什么可以进一步探索的点?

    作者写明统一审计只覆盖Python,并建议后续做联合评测和语义安全推理。

    作者指出的局限与后续方向

    • 语言范围:统一审计只做 Python。作者称,把协议扩到 Java 或 C/C++ 需要另建带测试套件的语料,这不在本次对抗鲁棒性研究范围内(第 4.3.2 节)。
    • 新基准:作者建议后续数据集把不安全/安全参考与测试配在一起,加入语义保持扰动,并扩展到 Python 以外(第 8 节原则 3)。
    • 威胁模型:作者建议按方法假设写明对手能力:白盒考虑训练时风险,如数据投毒和前缀劫持;黑盒考虑推理时威胁,如提示注入和语义保持释义(第 8 节原则 1)。
    • 语义推理:作者称当前方法建模的是表层句法,而安全是语义、非局部性质;后续方法应走向语义推理,并建立针对不变量和信息流、而不只是 CWE 模式的基准(第 8 节原则 7)。
    • 评测做法:作者建议把对抗测试列入评测,用多分析器交集而不是单一工具结论,并报告各攻击下的分布,而不只报平均(第 8 节原则 2、4、5)。结论称,若要在软件供应链中信任生成代码,应把对抗测试和安全–功能联合评测当作标准。
    • 论文没有独立的 Limitations 小节。第 7 节开头说会说明范围和局限,其后正文进入案例和第 8 节的实践建议。

    实验覆盖范围

    • 审计对象是 Sven、SafeCoder、PromSec。实际加载三个 CodeGen 前缀检查点和 CodeLlama-7B;PromSec 查询 GPT-3.5-Turbo(第 5 节)。
    • RQ1 的扰动包括 StudentStyle、InverseComment、SparseComment、SparseQuestion,以及对 PromSec 的 SafeComment、VulComment、DeadCode10/50、DeadFunc200、SensitiveDeadCode、In-Context(Table 2、Table 4)。RQ3 使用 InverseComment 与 StudentStyle(第 6.3 节)。
    • 统一指标归一化到 67 条补全提示乘 10 个样本,共 670 个期望文件。CodeSecEval 为 180 个 Python 任务、44 类漏洞,其中 SecEvalPlus 113 条(第 4.3.2 节、第 5 节)。
    • 分析器为 CodeQL 2.15.4、Bandit 1.8.6、temperature 0 的 GPT-4o,以及 CodeSecEval 单测。论文写 GPT-4o 在随机子集上人工抽查,未报告子集规模、一致性和重复次数。
    • Sven 与 SafeCoder 按确定性工件做单次运行;PromSec 每条提示一次生成。论文写没有采样分布,也未报告置信区间(第 5 节)。
  6. 总结一下论文的主要内容

    三种方法在联合评测下安全且功能的比例低,对抗释义后Sven的共识率降到3.4%。

    作者审计 Sven、SafeCoder、PromSec,看改写注释和文档后,生成代码是否还能同时安全、可执行。

    • 问题:现有评测把安全与功能拆开,静态告警减少不等于单测通过。部署中的默认对手是 black-box,只有查询权限,通过注释、docstring 或 issue 文本让服务输出不安全代码。
    • 做法:扰动保持任务和测试不变。补全侧有释义、线索反转和最小上下文;修复侧还有偏安全评论、不安全暗示、死代码和示例提示。统一评测用 CodeSecEval,CodeQL、Bandit、GPT-4o 和单测全部同意才算安全且功能。
    • 无攻击联合结果:共识安全且功能率为 Sven 7.0%、SafeCoder 10.2%、PromSec 15.5%;CodeQL 为 66.3%、64.8%、98.5%;不可执行占 46.0%、37.0%、60.0%(Table 5、Table 6)。
    • 对抗结果:CodeGen-2B 上 SVENsec 的无攻击安全率为 93.7%,正文称 InverseComment 绝对下降 13%。SafeCoder 在 CodeLlama-7B 上从 89.0% 降到 80.6%(Table 2)。StudentStyle 下共识率为 Sven 3.4%、SafeCoder 4.3%、PromSec 15.2%(Table 10)。PromSec 在其原协议下,Table 4 的安全率不降反升,最高 98%。
    • 作者结论:作者称这些方法的安全行为依赖提示表层,而不是稳定、可泛化的对齐;静态分析器给出的安全率高于可执行且通过全部检查的比例。作者建议评测写明威胁模型,加入对抗测试,并用安全与功能的交集,而不是单一静态工具的结论。
阅读原文arxiv.org