摘要
尽管静态代码分析(SCA)工具已集成到许多现代软件构建和测试管道中,但它们的实际影响仍然受到它们通常产生的过多误报警告的严重阻碍。为了解决这个问题,研究人员提出了几种后处理方法,旨在在 SCA 工具产生结果后过滤掉错误命中(或等效地识别“可操作”警告)。然而,我们发现这些方法中的大多数都是有针对性的(即仅处理少数 SCA 警告类型)并在综合基准或小规模手动收集的数据集(即典型样本量为数百)上进行评估。在本文中,我们提出了一个数据集,其中包含 224,484 个被开发人员修复(真阳性)或明确忽略(假阳性)的真实警告样本,我们使用数据挖掘方法从 GitHub 的 9,958 个不同的开源 Java 项目中收集了这些样本。此外,我们利用这个丰富的数据集来训练基于代码嵌入的机器学习模型,用于过滤由 160 种不同的 SonarQube 规则检查产生的误报警告,这是当今最广泛采用的 SCA 工具之一。这是我们在该领域所知道的最广泛的现实世界公共数据集和研究。我们的方法对 SonarQube 警告分类的准确率为 91%(最佳 F1 分数为 81.3%,AUC 为 95.3%)。
关键词:静态代码分析、过滤误报、真实数据集、代码嵌入、机器学习。
引言
静态代码分析 (SCA) 工具成为现代软件开发生命周期 (SDLC) 的一等公民。 SCA 工具相对快速、经济高效且易于与持续集成 (CI) 系统集成。他们分析软件的源代码,可以有效地检测各种类型的编程问题,如简单的编码错误、漏洞、性能问题或设计错误。
尽管 SCA 工具有许多有利的特性,但在软件开发实践中有效使用 SCA 工具仍然受到它们通常会产生过多的误报警告的阻碍。根据以往的研究,假阳性报告的比例可以达到 30-60%[1],[2]。大量的误报(即不可操作的错误报告)对 SCA 工具的应用具有严重的负面影响。它们可以压倒开发人员,从而掩盖可能在“堆底”未被发现的实际问题。因此,开发人员经常开始忽略 SCA 工具产生的大部分警告,并在最坏的情况下完全放弃它们 [3]、[4]。
SCA 工具产生如此多误报的核心原因包括不完善和浅层的静态代码分析(主要是为了保持合理的分析性能);在检测策略中应用过度近似;事实上,某些代码模式在某些情况下被认为是一个问题,但在其他情况下却不是,以及静态代码分析的固有局限性(即处理多态性、反射、指针分析)。
文献中提出了几种方法来处理这种不需要的情况,方法是对 SCA 工具结果进行排名、识别“可操作的警告”或过滤误报报告。早期的方法在 2000 年代后期开始出现,主要使用统计方法 [2]、[5]、[6] 来减少虚假报告的数量。后来,机器学习 (ML) 方法成为主导 [7]-[9],而最近的研究 [10]、[11] 侧重于应用自然语言处理 (NLP) 技术来表示警告的代码上下文并对警告进行分类使用 ML 模型的 SCA 报告。这种减少假阳性 SCA 报告的各种现有方法证明了该问题的理论和实践重要性。尽管如此,过去的研究存在几个共同的缺点,这使得减少假阳性 SCA 警告的问题总体上是一个悬而未决的问题。科克等人。 [10] 已经意识到,尽管应用 ML 技术对误报分析报告进行分类和过滤的初步结果很有希望,但由于缺乏详细的、大型的-规模的经验评估。他们还强调需要更大的真实世界程序数据集来验证先前工作的发现,这些工作主要是在综合基准上进行的。我们做了同样的观察,我们可以补充如下:我们发现之前所有关于误报过滤的工作都至少存在以下限制之一:i)过滤算法特定于有限的警告子集(通常对于 1-10 种特定类型)由一个或多个 SCA 工具生成; ii) 过滤方法在综合基准(如 OWASP 基准 [12] 或 Juliet [13])或小型手动评估数据集(通常在数百个警告样本的范围内)进行评估; iii) 呈现的评估数据集是公司特定的并且是封闭的;因此,无法复制和验证所提出的方法。
在本文中,我们尝试通过在 Java 源代码中展示一个新颖的、开放的数据集,该数据集包含 224,484 个真实世界标记的 SCA 警告(真假阳性组合),由 SonarQube 的 160 种不同规则检查生成,从而弥补先前研究中发现的差距。 14],是当今最流行的 SCA 工具之一 [15]-[17]。我们使用基于 NLP 和 ML 的误报警告过滤方法展示了这个丰富数据集的潜力。为了收集如此庞大的真实数据,我们利用了 GitHub 的受欢迎程度以及存储在那里的数百万个项目的可用性。我们采用数据挖掘技术创建了一个训练数据集,该数据集比我们所知道的任何其他现有的真实世界 SCA 报告数据集大一到三个数量级(通常比公开可用的开源数据集大 100 倍)。我们在数据集上训练了有效的 ML 模型,以使用基于 NLP 的代码上下文表示(即使用 word2vec [18] 嵌入源代码)来识别错误报告。我们选择嵌入来表示源代码,因为它消除了对手动特征工程的需要,并且基于 NLP 的代码表示在其他 SE 任务中也被证明是非常有效的 [19]、[20]。此外,与那些依赖符号执行 [21]、[22] 或为所有要分类的警告计算后向切片 [9] 的方法相比,该方法的计算成本更低。
我们的方法对 SonarQube 警告分类的准确率为 91%(最佳 F1 分数为 81.3%,AUC 为 95.3%)。最近依赖于类似于我们的 [10]、[11] 的 NLP 技术的工作也报告了有希望的结果;但是,它们仅针对少量手动标记的警告(即数百个)或封闭的专有数据集进行了验证,而我们的模型在包含 224,484 个标记警告的真实数据集上进行了验证条目。
这项工作的主要贡献可以总结如下:
- 一个真实世界的数据集,由 160 种不同类型的 47,015 个真阳性和 177,469 个假阳性 SonarQube 警告组成,使用数据挖掘技术从 GitHub 的 9,958 个不同的开源 Java 项目中收集;
- 一种轻量级和通用的基于 NLP 的源代码嵌入技术,用于表示 SCA 警告的本地上下文;
- 在数据集上训练的机器学习模型以高精度过滤由当今最流行的 SCA 工具之一 SonarQube 产生的误报警告。
本文的结构如下。在第二部分,我们列出了与我们相关的作品。我们在第三部分介绍了我们的数据收集和误报过滤方法。第四节描述了这些方法的经验评估结果。我们在第五节列出了对我们工作有效性的可能威胁,并在第六节结束了本文。