RepoSPD
Date: December 15, 2024
本文介绍了一种针对补丁的库级别的代码属性图(RepoCPG),同时使用渐进学习训练模型,使其同时学习到图和序列表示的知识,以实现更好的安全补丁检测。
Approach
RepoCPG构建
(1)生成文件级CPG:为pre-patch和post-patch补丁相应文件分别生成CPG图
(2)合并文件级CPG,生成MergeCPG:合并pre-CPG和post-CPG
为了合并CPG,作者将节点分为了3类:pre-patch node, post-patch node以及commen node。其中,common node就是补丁前后不变的节点。而pre-node和post-node有两种(1)pre-/post-patch中存在的节点,(2)与pre-/post-patch中单独存在的节点(changed node)依赖的节点。【我估计这样做是为了使单独删除/添加的语句的依赖关系也可以被捕捉到】
(3)合并库级别依赖,生成RepoCPG:a. 提取库级别函数调用图,b. 对MergeCPG中每个节点,检索是否存在函数调用依赖。如果存在,则将函数内依赖添加与节点相同的的标签(pre-/post-/common)。
(4)针对代码更改切片,生成slicing RepoCPG:a. 基于删除的库级别切片:只保留与pre-patch中删除的语句存在依赖关系的节点,b. 基于添加的库级别切片:只保留与post-patch中添加的语句存在依赖关系的节点。其中,依赖关系按照CDG和DDG判断,每个节点代表一个语句。
补丁表示
总体来说,就是用了图和序列两种表示方式。其中,图就是刚刚生成的slicing RepoCPG,而序列就是pre-/post-patch中的代码更改。然后作者用了一些AI方法,将这些内容表示成模型能理解的样子。
(1)Graph branch:对slicing RepoCPG中的节点生成节点向量,使用Graph Attention Networks捕捉边信息,等等
(2)sequence branch:只包括pre-patch和post-patch中的修改代码和版本信息
渐进学习 Progress Learning
(1)训练序列分支,冻结图分支的权重。
(2)训练图分支,冻结序列分支的权重。
(3)推理时按照加权公式同时使用两个分支的输出,得到最终结果。
Results
作者将本文方法(RepoSPD)使用SPI-DB即PatchDB两个数据集,与
(1)安全补丁检测方法:a. 监督训练方法(GraphSPD, PatchRNN),b. 预训练模型(CodeBERT, CodeT5, UniXcoder),c. 大语言模型(llama3-70b)
(2)静态检测方法(Cppcheck, RATS, Semgrep, Flawfinder, VUDDY)进行比较
(3)并分析了RepoSPD在不同漏洞类型上的表现
(4)以及RepoSPD的消融实验
SPI-DB:FFMPeg以及Qemu,包含25k补丁,其中10k为安全相关
PatchDB:348个开源仓库,包括36k代码片段,其中约12k为安全相关补丁。