Black-Box Adversarial Attacks on LLM-Based Code Completion >Proceedings of the 42nd International Conference on Machine Learning (ICML), 2025
研究背景与动机
研究背景
基于大语言模型(LLM)的代码补全引擎(如GitHub Copilot)因其强大的功能正确代码生成能力,正被数百万开发者广泛使用,显著提升了编程效率。然而,先前的研究表明,LLM容易生成带有危险安全漏洞的代码。更令人担忧的是,攻击者可能通过攻击代码补全引擎,大幅增加其生成漏洞代码的频率。现有的攻击方法(如投毒攻击)通常需要在白盒环境下修改模型的权重或训练数据,这要求攻击者能够访问模型的训练过程,而对于像GitHub Copilot这样的商业黑盒服务而言,这是不现实的。这些攻击通常还需要大量昂贵的计算资源。
研究动机与问题表述
本论文的动机是探究在更现实的黑盒威胁模型下,攻击代码补全引擎的可行性。具体的研究问题是:**攻击者能否在仅能操纵补全引擎输入(即查询)的黑盒设置中,以隐蔽的方式(即保持生成代码的功能正确性和响应速度)显著提高引擎生成不安全代码的比率?** 这种攻击之所以构成现实威胁,是因为:1) 黑盒假设与广泛部署的商业服务(如Copilot)的操作模式一致;2) 补全引擎的用户很可能接受有漏洞的代码建议,尤其是在攻击不影响引擎主要功能时;3) 攻击可以在后台隐蔽进行,用户难以察觉。
论文核心方法和步骤
论文提出了名为 INSEC 的首个高效黑盒对抗性攻击方法。其核心思想是设计一个对抗性函数 fadv,将原始查询 q转换为对抗性查询 fadv(q),从而定义一个被攻击的引擎 Gadv(q)=G(fadv(q))。INSEC通过以下关键组件实现这一目标:
攻击模板
INSEC将 fadv实例化为一个函数,该函数将一个固定的、简短的对抗性字符串 σ作为注释插入到查询 q中。插入位置是补全位置(c)的上一行,并且保持适当的缩进以维持代码的自然性。σ在推理时是预先计算好并固定不变的, indiscriminately 地插入到用户的所有查询中。这种设计确保了部署时的开销(延迟、计算)可忽略不计。
攻击优化
为了找到能有效提高漏洞率并保持功能正确性的攻击字符串 σ,INSEC采用了一种基于查询的随机优化算法(算法1)。该算法在一个小的训练数据集 Dvultrain上运行,其步骤如下:
初始化:使用多种策略(如随机初始化、TODO初始化、安全关键令牌初始化、反转初始化、清理器初始化)生成初始的攻击字符串候选池 P。
迭代优化:
变异:对当前候选池 P中的每个字符串,使用
mutate函数进行随机变异。该函数随机选择字符串中的一些令牌,并用从词汇表中随机采样的令牌替换它们。合并:将变异后的新候选字符串与旧的候选池合并,形成新的候选池 Pnew。
选择:使用
pick_n_best函数,根据攻击字符串在 Dvultrain上估计的漏洞率,从 Pnew中选择前 n个最佳候选进入下一轮迭代。漏洞率的计算基于公式(1):vulRate(G):=E(p,s)∼Dvul[Ec∼G(p,s)[1vul(p+c+s)]]
其中 1vul是漏洞判断函数(如静态分析器CodeQL)。
最终选择:优化循环结束后,在保留的验证集 Dvulval上选择最优的攻击字符串 σ。
攻击初始化策略
为了提高优化算法的收敛速度和性能,INSEC设计了五种不同的初始化策略来生成初始候选字符串:
随机初始化:从词汇表中均匀随机采样令牌。
TODO初始化:使用“TODO: fix vul”等字符串,暗示代码存在漏洞。
安全关键令牌初始化:比较安全和不安全补全的令牌差异,生成如“use {不安全令牌}”或“don’t use {安全令牌}”的指令。
清理器初始化:构造如“x = sanitizer(x)”的字符串,误导模型认为输入已被清理。
反转初始化:给定一个易受攻击的程序,让模型补全漏洞代码上方的注释,利用LLM学到的分布。

实验结果与结论
实验设置
目标模型:评估了INSEC在各种最先进的代码补全引擎上的效果,包括开源模型(StarCoder-3B, CodeLlama-7B, StarCoder2系列)和商业黑盒服务(OpenAI的GPT-3.5-Turbo-Instruct和GitHub Copilot)。
漏洞评估数据集:构建了一个包含5种流行编程语言中16种常见弱点枚举(CWE)的综合漏洞数据集 Dvul,每个CWE有12个安全关键补全任务。使用CodeQL静态分析器作为漏洞判断函数。
功能正确性评估:基于多语言版本的HumanEval创建数据集 Dfunc,使用标准的pass@k指标评估功能正确性,并定义相对差异度量passRatio@k:
passRatio@k(G′,G):=pass@k(G)pass@k(G′)
主要结果
攻击有效性:INSEC在所有被测试的补全引擎上均显著提高了不安全代码的生成率,绝对增幅超过50%(例如,在GPT-3.5-Turbo-Instruct上从约22%增至约73%)。同时,功能正确性下降相对较小(多数模型passRatio@1 > 78%),且更强的模型在攻击下能保留更多的功能正确性。
成本效益:攻击开发成本极低。例如,针对GPT-3.5-Turbo-Instruct优化一个CWE的攻击字符串,总成本低于10美元。对于开源模型,在商用GPU上约需6小时。
消融研究:
插入位置和格式:验证了将σ作为注释插入补全位置上一行的设计是最佳权衡选择。
初始化策略:安全关键令牌初始化策略最有效,但每种策略至少在某些场景下能产生最终的成功攻击。
优化与初始化:结合使用优化过程和初始化策略比单独使用任一种效果更好。
攻击令牌数量:5-10个令牌的攻击字符串通常能达到最佳效果。

扩展分析与案例
多CWE攻击:将针对不同CWE单独优化的攻击字符串串联起来,可以同时攻击多个漏洞,即使同时攻击16个CWE,漏洞率仍比未受攻击的引擎高出近2倍。
模型间泛化:针对一个模型优化的攻击字符串在一定程度上可以泛化到其他模型。
实际部署:论文开发了一个恶意的VSCode插件,可 stealthily 地将INSEC注入到GitHub Copilot扩展中,演示了攻击的现实可部署性。
结论与意义
INSEC是第一个能够在黑盒设置下有效操纵商业代码补全引擎,使其以高比率生成不安全代码同时保持功能正确性的攻击。该攻击利用LLM的指令跟随能力,通过一个轻量级的、预计算的注释字符串实现,具有成本低、易部署的特点。实验结果揭示了当前LLM代码生成系统一个严重的安全漏洞:即使是最先进的模型和服务,也容易受到这种隐蔽的对抗性攻击。鉴于INSEC的广泛适用性和高严重性,论文呼吁社区进一步研究并解决由基于LLM的代码生成系统引入的安全漏洞。论文还讨论了一些潜在的防御措施(如提示清洗、静态分析),但指出它们目前存在局限性。这项工作对代码补全服务提供商和用户敲响了安全警钟。