本文发表于 ICSE2024 会议中。
引入
在过去的漏洞数据库中,主要存在以下几种问题:
- 无效补丁(Tangled Patches):针对某个漏洞的补丁无法正确修复该漏洞
- 缺乏跨函数漏洞(Inter-procedural Vulnerabilities)
- 过时补丁(Outdated Patches):修复了该漏洞的补丁造成了全新的漏洞,导致该补丁过时
本文通过下面的方法构建一个解决了上述问题的数据库 ReposVul。
框架
本文设计的框架主要由以下四个部分所构成:原始数据获取,无效补丁判定,多粒度依赖关系分析,基于时间线的过时补丁过滤。
原始数据获取
本文收集的漏洞数据来自 Mend 这一漏洞数据库,对于 CWE 的漏洞数据则还收集了 CWE 漏洞编号和漏洞说明。本文分析所用的补丁则来自于 Github,还有一部分来自 Google 代码仓库 Android 和 Chrome。对于一个补丁,为了更好的分析函数间的修复情况,本文主要收集它的 commit ID、commit 信息、修改文件名以及它所修改的前后代码。
无效补丁判定
本文主要采用大模型和静态分析工具共同分析一个补丁是否有效。对于大模型,本文使用 prompt 预设大模型是一个漏洞分析专家,提供原始代码、漏洞修复代码等让大模型回答是或否以判定该修复是否有效。
同时为了更加准确的判定该补丁是否有效,本文针对不同的语言采用了不同的静态分析工具,如 C/C++ 使用 Cppcheck、Flawfinder、RATS、Semgrep 工具检测,Python 则使用 RATS 和 Semgrep,而 Java 则仅用 Semgrep。对于一个漏洞补丁是否有效,本文采用了首先对原始代码进行静态分析检测,随后将修复后的代码再次检测的方式来判定该补丁是否有效,如果同一漏洞依然存在则判定补丁无效。
最后将大模型和静态分析工具的检测结果进行合并,仅当二者判定均为有效或无效的时候才采用该补丁数据。
多粒度依赖关系分析
本文针对每个漏洞都进行了多层次的漏洞信息分析,主要分为以下四个层次:
- 仓库级:对于每个与漏洞修复相关的文件,本文提取整个仓库中漏洞之间的程序调用关系链。
- 文件级:本文将代码更改前后的与漏洞修复相关的文件分别视为易受攻击和不易受攻击。对于与漏洞修复无关的文件,将代码更改前后的文件都视为不易受攻击。
- 函数级:对于每个受代码更改影响的函数,如果该函数在漏洞修复相关文件中有定义,本文将代码更改前后的函数分别视为易受攻击和不易受攻击;如果该函数在漏洞修复无关的文件中有定义,本文将代码更改前后的函数都视为不易受攻击。
- 行级:提取该行的修改。
对于仓库级别的函数调用树(callerTree)和函数被调用树(calleeTree),使用如下算法分析获取:对于与漏洞修复相关的文件中每个变化的代码片段,首先识别出调用树和被调用树的根函数,分别命名为 callerRoot 和 calleeRoot。随后,使用特定的静态分析工具从 callerRoot 构建调用树,从 calleeRoot 构建被调用树。对于不同的编程语言,我们使用不同的工具:C/C++ 使用 CFlow,Java-all-call-graph 用于Java,Python 则使用 PyCG。
基于时间线的过时补丁过滤
本文首先将所有的 commit 过滤,清除掉对数据、日志文件或者说明文件的修改提交,仅关注某一单一文件的修改历史,对比最新当前版本和修改后的补丁是否一致,仅保留修改后和当前最新版本一致的补丁。
数据分析
本文的数据集相较于其他的漏洞数据集有如下的优点:
- 多粒度信息:与其他仅包含线级、函数级和文件级漏洞的数据集相比,ReposVul 包含了更全面的粒度,包括仓库级、文件级、函数级和线级漏洞,考虑了跨程序漏洞,并提供了比单一补丁更多的信息。ReposVul 包含了来自 6897 个补丁的 14706 个文件,包含了 212790 个 C 语言函数,20302 个 C++ 函数,2816 个 Java 函数,26308 个 Python 函数。
- 广泛的 CWE 覆盖:ReposVul 涵盖了比所有其他数据集更多的 CWE 类型。ReposVul 在 C 语言中涵盖了 149 个 CWE 类型,在 C++ 中涵盖了 105 个,在Java中涵盖了 129 个,在 Python 中涵盖了 159 个。ReposVul 涵盖了跨越各种编程语言的 CWE 类型,因为一些 CWE 类型不是特定于语言的。这表明 ReposVul 提供的数据比现有的基准测试更为全面。
- 有效的标记方法:之前的工作通过当前的标记方法识别了现有数据集中的噪声数据问题。在本文中,ReposVul 提出了一个用于提高漏洞数据质量的漏洞解绑模块。它涉及静态分析工具中的漏洞规则和领域知识以及 LLMs 的强上下文理解能力。
- 识别过时的补丁:当前的漏洞数据集无法区分过时的补丁。ReposVul采用基于轨迹的过滤模块来识别潜在的过时补丁。基于轨迹的过滤模块整合了基于文件路径的过滤器和基于提交时间的过滤器,以提供过时补丁的标签。
- 额外信息的特定丰富性:ReposVul 包含最丰富的额外信息,包括 CVE 描述、CVSS 和补丁提交历史,以及静态分析信息。关于漏洞的全面信息使开发者和研究人员能够采取有效的措施进行漏洞检测。
- 标签更为准确:在最先进的开源软件(OSS)漏洞数据集中,20-71% 的漏洞标签是不准确的。ReposVul 在 C、C++、Java 和 Python 上的标签准确率分别为 85%、90%、85% 和 80%。与现有OSS漏洞数据集相比,ReposVul实现了相对更高的准确率。在四种编程语言中,特别是 C++ 编程语言,其准确率高达 90%。我们的观察表明,由于大模型的上下文理解能力和静态分析工具的领域知识的整合,ReposVul 的标签质量优于以前的数据集。
本文还就不同大模型的漏洞识别能力进行了对比,结果如下:
本文的数据集在如下两个方面还可改进:
- 数据来源丰富度不足:在收集过程中,本文从 GitHub、Google Git 和 bugs.chromium 收集 ReposVul,这导致了一些在ReposVul 中托管在其他平台上的项目被遗漏。
- 编程语言种类不够丰富:本文只提取了四种广泛使用的编程语言的仓库级依赖。然而,其他语言也存在漏洞,例如 JavaScript、Go 和 PHP。
- 漏洞时间跨度不够长:本文只从 2010 年开始收集 CVE 漏洞,之前的 CVE 漏洞没有包含在 ReposVul 中,这导致一些漏洞可能在之前几年被发现并修复。