DiverseVul A New Vulnerable Source Code Dataset for Deep Learning Based Vulnerability Detection

0 Abstract

我们提出并发布了一个新的漏洞源代码数据集。我们通过抓取安全问题网站、从相应项目中提取漏洞修复提交和源代码来整理数据集。我们的新数据集包含跨越 150 个 CWE 的 18,945 个脆弱函数,以及从 7,514 个提交中提取的 330,492 个非脆弱函数。我们的数据集涵盖的项目数量比之前所有数据集的总和还要多 295 个。

结合我们的新数据集和以前的数据集,我们分析了使用深度学习检测软件漏洞所面临的挑战和有前景的研究方向。我们研究了属于 4 个系列的 11 种模型架构。我们的研究结果表明,由于误报率高、F1 分数低以及难以检测硬 CWE,深度学习在漏洞检测方面还没有做好准备。特别是,我们展示了部署基于深度学习的模型所面临的重要通用化挑战。我们表明,增加训练数据量可能不会进一步提高深度学习模型在漏洞检测方面的性能,但可能有助于提高对未见项目的泛化能力。

我们还确定了充满希望的未来研究方向。我们证明,大型语言模型(LLMs)是基于 ML 的漏洞检测的一个有前途的研究方向,在我们的实验中,其性能优于具有代码结构特征的图形神经网络(GNNs)。此外,开发针对源代码的预训练目标也是提高漏洞检测性能的一个有前途的研究方向。

1 Intro or Overview

为了使深度学习成功,我们需要一个大型的易受攻击的源代码数据集。我们发布了一个新的开放漏洞数据集,用于C/C++,名为DiverseVul。为了策划这个数据集,**我们爬取安全问题网站,收集漏洞报告,提取每个漏洞的漏洞修复提交,克隆相应的项目,并从中提取易受攻击和非易受攻击的源代码。**我们的数据集包含了18,945个易受攻击的函数和330,492个非易受攻击的函数,从7,514次提交中提取出来,涵盖了150个CWE。这比之前最大最多样化的数据集CVEFixes [2]中的C/C++数据大小超过两倍。我们的数据集更加多样化,覆盖的项目几乎比所有先前发布的数据集的组合多50%。我们向社区公开发布了DiverseVul数据集,网址为https://github.com/wagner-group/diversevul。

我们的新数据集使我们能够研究最先进的深度学习方法,并对基于ML的漏洞检测的有希望的研究方向以及挑战获得新的见解。我们研究了几个问题。更多的训练数据是否有帮助,还是模型饱和了?模型架构是否有重大影响?使用依赖代码结构特征的最先进模型更好,还是使用大型语言模型更好?更大的LLM是否比更小的LLM更好?进一步改进深度学习以用于漏洞检测的最有希望的方向是什么?

我们还探索了将大型语言模型(LLMs)应用于漏洞检测,因为LLMs在自然语言处理和代码理解方面已经取得了最先进的成果,尽管它们不使用代码结构特征。我们研究了这些模型在三个数据集上的表现:(1)CVEFixes [2],C/C++漏洞的最大先前发布数据集;(2)所有先前发布数据集的组合(Devign [33]、ReVeal [4]、BigVul [9]、CrossVul [19]、CVEFixes [2]),去重;(3)这些先前数据集和我们的DiverseVul的组合(详细信息见表3)。

我们的实验表明,在评估先前的数据集CVEFixes [2]时,模型架构几乎没有影响,LLMs的表现与GNNs大致相同。特别是在CVEFixes上,最大的先前发布的数据集上,ReVeal模型(GNN)实现12.8的F1分数,而LLMs的F1分数为8.5-16.3(见图1)。有人可能会从中得出精确架构几乎没有影响的结论。然而,当在更大的数据集上评估时,我们可以看到这一结论被扭转:LLMs的表现要比GNNs好得多。特别是,当我们将所有先前发布的数据集与我们的DiverseVul结合时,最好的LLM实现了47.2的F1分数,而ReVeal为29.8。这些实验表明,我们需要大规模数据集来可靠评估深度学习方法对漏洞检测的影响,随着可用培训数据量的增加,不同架构的相对性能会发生根本性变化:培训数据量增加5倍(从CVEFixes到所有数据集)将我们最佳模型的表现从10.5提高到48.9的F1分数。它们表明,LLMs比GNNs更能够利用大规模数据集:**更大的数据集仅轻微提高了ReVeal的表现,但显著提高了LLMs的表现。**然而,==我们的实验表明,通过收集更多数据来提高性能可能已经停滞。==通过将我们的数据集添加到先前数据集的组合中,我们可以提高11种模型中的7种模型的测试性能。然而,对于性能排名前三的模型,我们要么看不到改进,要么改进很小(详见4.2节)。

不幸的是,最新的深度学习技术仍未准备好进行漏洞检测。我们最佳模型的F1分数为47.2%,真正阳性率为43.3%,假阳性率为3.5%。假阳性率仍然太高,以至于模型在实践中无法发挥作用。一个项目可能包含成千上万个功能,这个假阳性率对应着数百个假阳性,这比大多数分析人员愿意翻阅的数量要多。尽管存在挑战,图1表明,大型语言模型(LLMs)可能在基于深度学习的漏洞检测方面表现更好。在之前的论文中,研究人员认为具有代码结构特征的GNN对于漏洞检测是有前途的,因为它结合了领域知识和深度学习。相比之下,我们的结果表明,**大型语言模型(RoBERTa、GPT-2和T5系列)在训练更多数据时明显优于最新的GNN,**特别是CodeT5模型(CodeT5 Small、CodeT5 Base、NatGen)表现最好。与普遍认为对于LLMs表现良好,模型大小是最重要因素不同,我们的结果显示,最重要的因素可能是LLM的训练方式。在代码理解任务的预训练似乎能够带来很大的改善。例如,**CodeT5 Small被预训练用于预测变量和函数名称,它的平均F1分数比两倍于它的大小但未在代码上进行预训练的模型高出8个百分点。**令人惊讶的是,我们发现在自然语言方面有效的预训练任务对漏洞检测帮助不大。相反,看来我们需要代码特定的预训练任务。我们认为开发更好的代码特定预训练任务是改善基于深度学习的漏洞检测的一个有前途的研究方向。

此外,我们确定了一个部署基于深度学习模型的重要泛化挑战。要部署一个模型,我们需要检测新软件项目中的漏洞,这些漏洞在训练集中没有出现。我们发现,在这种情况下,深度学习模型表现非常糟糕。特别是,过去的工作将数据分为训练集和测试集,通过随机分割漏洞,而不考虑每个漏洞出现在哪个项目中。然而,在实践中,我们经常希望在新项目上运行漏洞检测工具,因此在训练集中不会有该项目的任何漏洞。为了评估深度学习在这种情况下的性能,**我们留出了一组项目,我们称之为“未见项目”;我们使用来自其他项目的漏洞进行训练(“已见项目”),然后在未见项目中测试。**所有模型在未见项目上的性能显著下降,例如,在已见项目上的F1分数从49%降至未见项目上的仅9.4%。原因不明;也许模型过度拟合了特定于出现在训练集中的特定项目的模式或编码习惯。 我们希望未来的研究能够探讨如何解决这个问题。我们建议在训练损失中使用类别权重进行简单干预,这在这个方向上迈出了一小步,但差距仍然很大,需要更多的工作。

最后,我们量化了数据集中的标签噪声以及先前的数据集。 标签噪声是基于机器学习的漏洞检测研究面临的重要挑战。 为了从漏洞修复提交中提取易受攻击的函数,我们遵循了最先进的方法(由Devign [33]、ReVeal [4]、BigVul [9]、CrossVul [19]、CVEFixes [2]使用),我们将这些提交更改的函数标记为易受攻击。为了了解这种标记方法的标签准确性,我们从我们的数据集中随机抽取50个易受攻击的函数,另外从收集NVD提交的三个数据集的并集(BigVul、CrossVul和CVEFixes)中抽取50个易受攻击的函数。然后,我们手动分析漏洞和标记的易受攻击函数。我们的结果发现DiverseVul中易受攻击函数的标签准确率为60%,比CVEFixes、BigVul和CrossVul的并集高出24%,但仍存在许多标签错误。主要挑战是漏洞分布在多个函数中以及在漏洞修复提交中对非易受攻击函数的更改。我们希望我们的工作迈出了解决标签噪声问题的第一步,并强调了深入调查标签噪声影响的必要性。

本文作出如下贡献:

• 我们发布了DiverseVul,一款新的C/C易受攻击源代码数据集。我们的数据集比以前最大的C/C数据集大60%,并且比所有以前的数据集更多样化。

• 我们研究了来自4个不同模型系列的11种模型架构。我们的结果表明,大型语言模型在基于深度学习的漏洞检测方面优于最先进的图神经网络,并且开发源代码特定的预训练目标是一个有前途的研究方向。

• 我们确定了深度学习在漏洞检测中面临的挑战。特别是,我们强调了将泛化到培训集之外的未看到的项目的困难。

• 我们评估了我们数据集中和依赖于漏洞修复提交的以前数据集中的标签噪声。

1.1 Problem and Challenge

深度学习模型在漏洞检测上能够成功的一个重要条件是庞大的漏洞代码数据样本的支撑,我们需要大规模数据集来可靠评估深度学习方法对漏洞检测的影响,随着可用培训数据量的增加,不同架构的相对性能会发生根本性变化。LLMs比GNNs更能够利用大规模数据集:**更大的数据集仅轻微提高了ReVeal的表现,但显著提高了LLMs的表现。**然而,我们的实验表明,通过收集更多数据来提高性能可能已经停滞。与普遍认为对于LLMs表现良好,模型大小是最重要因素不同,我们的结果显示,最重要的因素可能是LLM的训练方式。在代码理解任务的预训练似乎能够带来很大的改善。我们认为开发更好的代码特定预训练任务是改善基于深度学习的漏洞检测的一个有前途的研究方向。

此外,我们确定了一个部署基于深度学习模型的重要泛化挑战。要部署一个模型,我们需要检测新软件项目中的漏洞,这些漏洞在训练集中没有出现。我们发现,在这种情况下,深度学习模型表现非常糟糕。然而,在实践中,我们经常希望在新项目上运行漏洞检测工具,因此在训练集中不会有该项目的任何漏洞。所有模型在未见项目上的性能显著下降,例如,在已见项目上的F1分数从49%降至未见项目上的仅9.4%。原因不明;也许模型过度拟合了特定于出现在训练集中的特定项目的模式或编码习惯。

1.2 Motivation

更多的训练数据是否有帮助,还是模型饱和了?

模型架构是否有重大影响?

使用依赖代码结构特征的最先进模型更好,还是使用大型语言模型更好?

更大的LLM是否比更小的LLM更好?

进一步改进深度学习以用于漏洞检测的最有希望的方向是什么?

3 Experiment and Evaluation

3.2 Evaluation

**结果1:当在所有可用数据上进行训练时,大型语言模型明显优于最先进的基于 GNN 的 ReVeal 模型。**当在所有可用数据(以前 + DiverseVul)上进行训练时,LLMs的表现显著优于ReVeal模型:ReVeal模型实现了29.76的F1分数,而LLMs的F1分数为31.96至47.15。最佳的LLM在这个大型训练集上表现明显优于ReVeal。比较ReVeal和LLMs可能是不公平的,因为ReVeal的参数数量比LLMs少1-2个数量级。我们不知道更大的GNN是否能与LLMs竞争。不幸的是,即使是表现最好的模型NatGen,也还不适合部署在漏洞检测中,具有3.47%的误报率和47.15%的F1分数。这种误报率仍然太高,不够实用,而F1分数仍然偏低。尽管如此,我们相信大型语言模型在基于深度学习的漏洞检测领域具有潜力。有趣的是,LLMs需要大量的训练数据才能超越ReVeal。当仅在CVEFixes数据上进行训练时,这是一个更小的训练集,LLMs相对于基于GNN的ReVeal模型并没有明显的优势,在这种情况下,ReVeal甚至比LLMs中的6个(共10个)更好。

**结果2:在三个基本LLM模型中,T5 Base在漏洞检测中表现优于RoBERTa和GPT-2 Base。**RoBERTa只使用编码器,GPT-2只使用解码器,而T5使用编码器-解码器Transformer层。当在以前+DiverseVul上进行训练时,T5 Base的测试F1分数分别比RoBERTa和GPT-2 Base高7.35%和9.3%。因此,编码器-解码器架构可能比仅解码器/编码器架构具有优势。

**结果3:在代码上进行预训练,如果我们只使用自然语言预训练任务,并不会显著提高漏洞预测。**代码模型CodeBERT、GraphCodeBERT、CodeGPT、PolyCoder并不比相应的文本模型RoBERTa和GPT-2 Base显著更好。具体来说,当在Previous数据集上进行训练时,CodeBERT和GraphCodeBERT的表现与RoBERTa类似。当在Previous + DiverseVul数据集上进行训练时,CodeBERT和GraphCodeBERT将F1分数提高了最多达到2.8%,相比于RoBERTa。

**结果4:在C/C上进行特定于代码的预训练任务对改进漏洞检测性能有很大影响。**两个CodeT5模型和NatGen模型具有最佳的F1分数。它们是使用C/C上的代码特定预训练任务进行预训练的。CodeT5模型使用标识符感知的预训练任务:掩码标识符预测和标识符标记。NatGen在CodeT5的基础上进行额外的代码自然化预训练,例如删除死代码和重命名变量。这些预训练任务要求模型了解基本代码理解,这显著提高了用于漏洞检测任务的微调模型性能。请注意,GraphCodeBERT还进行了一些特定于代码的预训练,以从具有数据流的一对变量中学习嵌入,从而使点积值较大。然而,由于它没有在C/C++数据上进行训练,目前尚不清楚这种预训练任务对漏洞预测是否有效。

**结果5:特定于代码的预训练任务比模型大小更重要。**在表4中最好的三个模型中(CodeT5 Small,CodeT5 Base,NatGen),CodeT5 Small模型只有60M个参数,是RoBERTa模型和GPT-2模型大小的一半,并且是其他T5模型大小的不到三分之一。然而,CodeT5 Small的性能与最大的CodeT5 Base和NatGen模型非常相似,并且优于所有其他模型。与认为较大模型往往会产生更好性能的信念相反,我们的结果表明,特定于代码的预训练任务对漏洞检测的模型大小更为重要。

**结果6:从收集更多数据集中获得的性能提升可能已经达到饱和。**图2可视化了在DiverseVul + Previous数据上训练对比仅在Previous数据上训练有多大帮助提高漏洞检测性能。将DiverseVul添加到训练集中,平均提高了7种模型的F1分数2.4%,与仅使用Previous数据集训练相比。然而,这并没有帮助最佳表现的CodeT5模型,对NatGen的帮助也只是适度的。尽管通过在合并的Previous数据集上训练来提高模型性能的改进较大,但收集不同的数据集可能不会进一步改善这一点。

**结果7:增加训练数据集的数量,来自相同分布,有助于漏洞检测。**我们的结果显示,使用来自相同分布的更大数据集进行训练可以提高测试性能。

**结果8:深度学习模型在漏洞检测任务中普遍存在一个重要挑战,即通用化到未知测试项目。**AI用于代码的一个流行应用案例是GitHub CoPilot,其中AI模型在开发人员编写代码时建议如何完善代码。

**结果 9:使用类权重进行交叉熵损失可以提高模型对未知项目的泛化性能,但仍有很大的改进空间。**如果训练/测试样本来自相同分布,类权重也可以提高模型的性能。表6显示了使用不同方案微调的模型的评估结果。在已知/未知项目实验中,使用类权重可以提高三种模型架构的F1分数。项目平衡的批量采样器对泛化无帮助。加权软F1损失有助于CodeBERT和CodeT5 Small的泛化,但对已知项目的性能有损害。总的来说,类权重是最佳方案,因为它提高了已知和未知项目的性能。使用类权重训练的CodeT5 Small在未知项目上的测试F1分数最高(17.21%)。

**结果10:一些CWEs比其他CWEs容易学习,而不受训练数据大小的影响。**表7显示了CodeT5基础模型在37个CWEs上的预测性能。我们已经用粗体突出显示了培训集中最常见的10个CWEs和最高的真阳性率(TPR)数字。请注意,所有CWEs具有相同的假阳性率(FPR),因为FPR仅与非易受攻击的功能相关。

image-20250107211606964

4 Discussion

Conclusion