浙江大学学报(工学版), 2025, 59(8): 1644-1652 doi: 10.3785/j.issn.1008-973X.2025.08.011

计算机技术、控制工程、通信技术

基于异构图表征的源代码漏洞检测方法

张学军,, 梁书滨, 白万荣, 张奉鹤, 黄海燕, 郭梅凤, 陈卓

1. 兰州交通大学 电子与信息工程学院,甘肃 兰州 730070

2. 国网甘肃省电力公司 电力科学研究院,甘肃 兰州 730070

Source code vulnerability detection method based on heterogeneous graph representation

ZHANG Xuejun,, LIANG Shubin, BAI Wanrong, ZHANG Fenghe, HUANG Haiyan, GUO Meifeng, CHEN Zhuo

1. College of Electronic and Information Engineering, Lanzhou Jiaotong University, Lanzhou 730070, China

2. Electric Power Research Institute, State Grid Gansu Electric Power Company, Lanzhou 730070, China

收稿日期: 2024-08-21  

基金资助: 国家自然科学基金资助项目(61762058, 62461032);甘肃省教育厅产业支撑项目(2022CYZC-38);甘肃省重点研发计划资助项目(25YEFA089);国家电网科技资助项目(W32KJ2722010, 522722220013).

Received: 2024-08-21  

Fund supported: 国家自然科学基金资助项目(61762058,62461032);甘肃省教育厅产业支撑项目(2022CYZC-38);甘肃省重点研发计划资助项目(25YEFA089);国家电网科技资助项目(W32KJ2722010,522722220013).

作者简介 About authors

张学军(1977—),男,教授,博导,从事网络安全、数据隐私与机器学习的研究.orcid.org/0000-0002-0350-359X.E-mail:xuejunzhang@mail.lzjtu.cn , E-mail:xuejunzhang@mail.lzjtu.cn

摘要

针对现有的源代码漏洞检测模型对异构特征和底层信息提取不足导致的检测准确率不高的问题,提出基于异构图表征的源代码漏洞检测方法. 从中间代码表示(IR)中提取8种指令级特征作为程序依赖图的节点嵌入,解决底层信息提取不足的问题. 在节点层和依赖层分别构建基于注意力机制的聚合模块来提取图表征数据中的异构性特征,通过调整注意力系数捕获关键节点信息. 对图数据的聚合结果进行分类,预测是否存在漏洞. 在合成数据集和2个真实项目数据集上的实验表明,相比于现有方法,本文方法具有更强的异构特征提取能力和更高的漏洞检测综合性能.

关键词: 漏洞检测 ; 图表征 ; 注意力机制 ; 异构特征 ; 中间代码表示

Abstract

A source code vulnerability detection method based on heterogeneous graph representation was proposed aiming at the problem of low detection accuracy caused by the insufficient extraction of heterogeneous features and low-level information in the existing source code vulnerability detection models. Eight instruction-level features were extracted from the intermediate code representation (IR) to serve as node embeddings for the program dependence graph, which addressed the issue of missing low-level information. Attention aggregation mechanisms were constructed at the node level and dependency level respectively to extract heterogeneous features, and information of key nodes was extracted by adjusting attention coefficients. The aggregated results of the graph data were classified to predict the presence of vulnerability. The experiments on synthetic data sets and two real project data sets show that the proposed method has stronger capabilities in extracting heterogeneous features and higher comprehensive performance in vulnerability detection compared with existing methods.

Keywords: vulnerability detection ; graph representation ; attention mechanism ; heterogeneous feature ; intermediate code representation

PDF (778KB) 元数据 多维度评价 相关文章 导出 EndNote| Ris| Bibtex  收藏本文

本文引用格式

张学军, 梁书滨, 白万荣, 张奉鹤, 黄海燕, 郭梅凤, 陈卓. 基于异构图表征的源代码漏洞检测方法. 浙江大学学报(工学版)[J], 2025, 59(8): 1644-1652 doi:10.3785/j.issn.1008-973X.2025.08.011

ZHANG Xuejun, LIANG Shubin, BAI Wanrong, ZHANG Fenghe, HUANG Haiyan, GUO Meifeng, CHEN Zhuo. Source code vulnerability detection method based on heterogeneous graph representation. Journal of Zhejiang University(Engineering Science)[J], 2025, 59(8): 1644-1652 doi:10.3785/j.issn.1008-973X.2025.08.011

随着市场对软件安全需求的提升,针对软件漏洞的检测成为该领域的研究热点[1]. 近年来,国内外学者提出使用静态测试和动态分析的方法对源代码漏洞进行检测与分析. 动态分析在面对大型复杂软件系统的漏洞时,存在检测率较低的问题. 与动态分析相比,静态测试能够在不实际运行程序的情况下发现源代码中的安全漏洞,解决了动态分析无法完全覆盖所有代码的问题,得到了研究者的高度重视. 静态测试主要包括模式匹配[2]、规则检查[3]和基于学习的方法[4]. 模式匹配和规则检查严重依赖人工,对未定义的漏洞模式缺乏识别能力. 利用基于学习的方法,能够有效避免因人工定义导致的漏洞模式不全的问题,该方法成为静态测试的主要手段之一.

Li等[5]利用双向长短时记忆网络检测漏洞,但其严重依赖上下文,捕获长距离依赖关系的能力有限. 为了提取更丰富的语法和语义信息,SySeVR扩充了4种漏洞语法规则[6]. 上述方法只在源代码层面提取漏洞特征,缺乏对底层逻辑的有效提取. Li等[7]从中间代码表示(IR)中提取特征,构建样本切片和代码语句之间的关联,实现了细粒度检测. 将IR视为纯文本会影响模型对程序底层逻辑的学习,且过短的切片不利于漏洞信息的远距离传播. Wu等[8-9]分别采用卷积神经网络和图神经网络(graph neural network, GNN)提取特征,取得了更高的准确率,但传统GNN对异质图的泛化能力不足. Wang等[10-11]采用改进的GNN,通过拼接方式融合异构依赖关系. 拼接会使得依赖层异质性缺失,降低漏洞模式的自适应能力.

针对上述问题,本文提出基于异构图表征的源代码漏洞检测方法(vulnerability detection based on heterogeneous graph, VulHetG). 生成源代码对应的IR,提取8种指令级别的特征用于代替源代码特征空间构造,解决了源代码底层信息缺失导致的检测率低的问题. 分别在PDG的节点层和依赖层构建基于图注意力网络(graph attention network, GAT)和自注意力的分层聚合机制,考虑每个异构因子的重要性. 通过调整注意力系数来提高关键节点的权重,降低因传统切片引起的长距离依赖损失. 在合成数据集和真实数据集上的实验结果表明,VulHetG在合成数据集上的准确率较5种基线方法分别提高了1%、1.3%、2%、17.5%和26.3%,在真实数据集上的准确率较3种基线方法分别提高了7%、38%和45.5%.

1. 相关工作

基于规则的检测方法通过预定义的漏洞规则,对源代码文件进行遍历和匹配,找到潜在的漏洞威胁,但此类方法对漏洞规则具有很强的依赖性. 检测工具PMD[12]涵盖了编码规范、设计原则和安全漏洞等规则,以应对复杂的代码场景. 工具SonarQube[13]在可靠性、适用性方面进行了提升,不仅提供了多维度的代码质量评估,而且支持多种编程语言的检测任务. 基于学习的检测方法分为基于机器学习和基于深度学习的检测方法. Perl等[14]将GitHub提交记录映射到已知漏洞,使用支持向量机来标记可能存在漏洞的样本,但该方法在实际检测中存在较高的假阳性率. 相比之下,基于深度学习的方法更有利于深层次特征的提取.

基于深度学习的检测方法通常采用Token或图形的方式对源代码进行表征. μVulDeePecker[15]在VulDeePecker[5]的基础上引入代码小工具来细化漏洞特征提取,获得了多类型漏洞检测能力. 相比于Token,图表征对代码结构的表达更加清晰和显式化. Feng等[16]验证了多种GNN模型,获得了优于Token表征的检测结果,但GNN难以充分提取图表征中的异构信息. 徐泽鑫等[17]通过解耦、融合的方式获得了高质量特征,并利用距离损失放大漏洞样本的差异性降低了误报率. 程靖云等[18]以不相交图的形式拼接子图,采用多头图注意力网络(multi-head graph attention network, MHGAT)跨图层传递信息,有效提取了图数据异构特征. 以上方法虽然考虑了图数据异构性,但存在特征分布稀疏问题. Wang等[10]利用门控图神经网络(gated graph neural network, GGNN),在表示特定依赖的子图之间提取异构特征,Fan等[11]采用圆形GGNN融合张量中的异构信息. 虽然这2种方法对图数据异构特征的考虑更深入,但缺乏对异构元素的独立提取和重要性评估,导致隐秘的漏洞节点和边在聚合过程中被忽视. 本文针对异构特征提取不充分的问题,提出基于异构图的源代码漏洞检测方法.

2. VulHetG方法的设计

VulHetG方法的整体框架如图1所示,分为4个部分:表征构建、特征嵌入、节点层聚合、依赖层聚合与漏洞检测.

图 1

图 1   VulHetG方法的整体架构

Fig.1   Framework of VulHetG method


2.1. 表征构建

图1(a)所示,本文通过底层虚拟机(low-level virtual machine, LLVM)编译器前端Clang[19],生成中间代码LLVM-IR[20]和AST,利用Pass[21]提取依赖信息以生成PDG.

为了解决底层信息提取不足的问题,从Mirsky等[22]提供的C/C++项目中,提取8种指令级特征:节点编号、内置函数、静态赋值、操作指令、条件分支、变量、变量类型、原函数. 以8种指令级特征之一的“操作指令”为例,与源代码信息进行对比,如表1所示.

表 1   “操作指令”与源代码信息的对比

Tab.1  Comparison of “operation instructions” and source code

类型LLVM-IR数量源代码(举例)
算数指令add,sub…12+, −, *, /, %
位指令shl,lshr…6<<, >>, &, |, ^
转换指令trunc,zext…9char b = 97
内存指令load,store…3free *ptr
比较指令icmp,fcmp…2>, <, ==
分支指令call,ret,br…3goto label
异常处理landingpad…2std::exception
向量指令llvm.vector…3vec[3] = 5
原子指令atomicrmw…3fetch_add()
聚合指令insertvalue…4struct S{float x}
其他指令select,phi…3condition ? a : b

新窗口打开| 下载CSV


“操作指令”具有确定数量的特征项,通过指令名称可以精确地描述程序的运行逻辑,例如load、store和alloca清晰地描述了内存的读取、存储和分配. 这8种指令级特征是通过统计所有项目中的LLVM-IR指令并对其分类后得到,它们与程序运行逻辑密切相关,能够覆盖的漏洞范围超过了4种漏洞语法规则[6].

2.2. 特征嵌入

为了将特征作用到PDG的每个节点中,设计特征嵌入算法,相关定义如下.

定义1 源代码. ${{P}} = \{ {p_1},{p_2},{p_3},\cdots ,{p_n}\} $,其中${p_i}\left( {1 \leqslant i \leqslant n} \right)$表示源代码中的一条语句,由一组令牌序列构成,包括变量标识符、函数标识符、常量、关键字及运算符.

定义2 漏洞语法规则. ${{R}} = \left\{ {{r_k}} \right\}$$1 \leqslant k \leqslant 4$. 其中${{R}}$表示4种语法规则,${r_1}$表示API/库函数调用,${r_2}$表示指针调用,${r_3}$表示算数表达式,${r_4}$表示数组操作.

定义3 指令级特征. ${{L}} = \left\{ {{l_m}} \right\}$$1 \leqslant m \leqslant 8$. 其中${{L}}$表示从LLVM-IR中提取的8种指令级特征:节点编号、操作指令、内置函数、静态赋值、条件分支、变量、类型、原函数.

定义4 嵌入后的PDG. 嵌入特征的图数据用${{G}} = \left\{ {{{\boldsymbol{f}}_{\text{T}}},{{\boldsymbol{M}}_{{\text{DDG}}}},{{\boldsymbol{M}}_{{\text{CDG}}}}} \right\}$表示,其中$ {{\boldsymbol{f}}_{\text{T}}} $为特征张量,${{\boldsymbol{M}}_{{\text{DDG}}}}$${{\boldsymbol{M}}_{{\text{CDG}}}}$为数据依赖和控制依赖的邻接矩阵.

为了将特征作用于PDG的节点,VulHetG将从LLVM-IR提取的8种指令级特征嵌入到PDG节点中,具体嵌入过程如算法1所示.

算法1 特征嵌入算法

输入:源代码${{P}}$、语法规则${{R}}$、指令级特征${{L}}$

输出:${{G}} = \left\{ {{{\boldsymbol{f}}_{\text{T}}},{{\boldsymbol{M}}_{{\text{DDG}}}},{{\boldsymbol{M}}_{{\text{CDG}}}}} \right\}$、集合${{{N}}_{\text{G}}}$

1) 根据${{P}}$生成PDG和LLVM-IR,PDG节点集合为${{N}}$,单个节点${n_i} \in {{N}}$.

2) ${{\boldsymbol{M}}_{{\text{DDG}}}} \leftarrow $提取PDG中的数据依赖关系.

3) ${{\boldsymbol{M}}_{{\text{CDG}}}} \leftarrow $提取PDG中的控制依赖关系.

4) ${{\boldsymbol{f}}_{\text{T}}} \leftarrow \varnothing $${{{N}}_{\text{G}}} \leftarrow \varnothing $

5) for each ${n_i} \in {{N}}$ do:

6)  ${f_i} \leftarrow \varnothing $

7)  ${\text{I}}{{\text{R}}_i} \leftarrow $LLVM-IR中${n_i}$对应的片段

8)  for each ${l_m} \in {{L}}$ do:

9)   ${f_i} \leftarrow {f_i} \oplus {{\mathrm{Word}}} {\mathrm{2Vec}}\left( {{\text{I}}{{\text{R}}_i} \cap {l_m}} \right)$

10)  end for

11)  ${{\boldsymbol{f}}_{\text{T}}} \leftarrow $堆叠$\left( {{{\boldsymbol{f}}_{\text{T}}},{f_{{{\mathrm{i}}}}}} \right)$

12)  if ${n_i} \in {{R}}$ then

13)   ${{{N}}_{\text{G}}} \leftarrow {{{N}}_{\text{G}}} \cap {n_i}$

14)  end if

15)end for

16)return ${{G}} = \left\{ {{{\boldsymbol{f}}_{\text{T}}},{{\boldsymbol{M}}_{{\text{DDG}}}},{{\boldsymbol{M}}_{{\text{CDG}}}}} \right\}$${{{N}}_{\text{G}}}$

步骤1)表示准备阶段,根据源代码生成对应的PDG和LLVM-IR.

步骤2)、3)表示生成阶段,提取PDG中不同的依赖关系,构建数据依赖图(data dependency graph, DDG)和控制依赖图(control dependency graph, CDG)对应的邻接矩阵.

步骤4)~11)表示嵌入阶段,先为图数据定义特征空间$ {{\boldsymbol{f}}_{\text{T}}} $和节点候选集${{{N}}_{\text{G}}}$,然后遍历PDG节点,在每个节点对应的LLVM-IR片段${\text{I}}{{\text{R}}_i}$上提取${{L}}$中的特征,共得到8个不同的特征值. 利用Word2Vec算法将每个特征值转化为一维向量,再将它们拼接成1个完整的一维向量作为节点特征${{\boldsymbol{f}}_i}$的填充. 最后,将所有的节点嵌入堆叠成1个二维张量,将它作为图数据特征空间$ {{\boldsymbol{f}}_{\text{T}}} $的填充.

步骤12)~14)为关键节点提取阶段,根据漏洞语法规则${{R}}$,在遍历过程中提取符合语法规则的节点,并纳入候选集${{{N}}_{\text{G}}}$中.

步骤16)为输出阶段,返回嵌入后的图${{G}}$和节点集${{{N}}_{\text{G}}}$.

2.3. 节点层聚合

PDG经过特征嵌入,输出图${{G}}$和节点集${{{N}}_{\text{m}}}$,先将${{G}}$切分为${{{G}}_1}$${{{G}}_2}$

$ {{{G}}_1} = \left\{ {{{\boldsymbol{f}}_{\text{T}}},{{\boldsymbol{M}}_{{\text{DDG}}}}} \right\} , $

$ {{{G}}_2} = \left\{ {{{\boldsymbol{f}}_{\text{T}}},{{\boldsymbol{M}}_{{\text{CDG}}}}} \right\} . $

在节点聚合层,${{{G}}_1}$${{{G}}_2}$的聚合过程相同,这里以${{{G}}_1}$为例进行说明. GAT先依据${{\boldsymbol{M}}_{{\text{DDG}}}}$确定存在依赖关系的节点$i$$j$,再依据$i$$j$分别在$ {{\boldsymbol{f}}_{\text{T}}} $中计算两点之间的注意力系数${e_{ij}}$

$ {e_{ij}} = {\boldsymbol{a}}^{\mathrm{T}}\left( {{\boldsymbol{W}} {{\boldsymbol{h}}_i} \oplus{\boldsymbol{W}} {{\boldsymbol{h}}_j}} \right) . $

式中:${{\boldsymbol{h}}_i}$${{\boldsymbol{h}}_j}$分别为节点$i$$j$的特征向量,${\boldsymbol{a}}$${\boldsymbol{W}}$分别为可学习的系数向量和权重矩阵. 为了提高${{{N}}_{\text{G}}}$中节点在聚合过程中的关注度,对相关的注意力系数进行调整.

$ \tau \left[ j \right] = \left\{ \begin{aligned} &{{{\text{2,}}j \in {{{N}}_{\text{G}}}}} ;\\&{{\text{1,其他.}}}\end{aligned}\right. $

$ {e_{ij}} = \tau \left[ j \right] \cdot {e_{ij}}. $

式中:$ \tau $为调整系数. 在本文的设计中,当节点$j$属于${{{N}}_{\text{G}}}$(符合4种漏洞语法规则的节点集)时,$ \tau = 2 $,即${e_{ij}}$变为原来的2倍,从而在GAT网络聚合邻域信息时,提高对节点$j$的关注度;反之,则保持原来的${e_{ij}}$不变. 该注意力系数调整方法借鉴了可解释性的研究工作[23],利用干预学习中的权重调整操作,对重要节点的注意力系数进行倍数扩大来提高重要节点的聚合权重. 式(6)的归一化计算保证了系数调整的合理性:

$ {\alpha _{ij}} = \frac{{\exp \left( {{{\mathrm{LeakyReLU}}} \left( {{e_{ij}}} \right)} \right)}}{{\displaystyle \sum\nolimits_{v \in {{N}}\left( i \right)} {\exp \left( {{{\mathrm{LeakyReLU}}} \left( {{e_{iv}}} \right)} \right)} }}. $

式中:${{N}}\left( i \right)$为节点$i$的所有邻居节点集合;${{\mathrm{LeakyReLU}}} $为非线性激活函数;exp为指数函数,作用是放大注意力系数之间的差异. 在得到节点的${\alpha _{ij}}$后,计算多头注意力的输出结果,得到节点$i$的更新向量表示:

$ {{\boldsymbol{h}}_i}^\prime = {\text{ }}\mathop \parallel \nolimits_{k = 1}^K \sigma \left( {\sum\limits_{j \in N\left( i \right)} {\alpha _{ij}^k{{\boldsymbol{W}}^k}{{\boldsymbol{h}}_i}} } \right) . $

式中:$\sigma $为激活函数,$K$为注意力头个数,$\alpha _{ij}^k$${{\boldsymbol{W}}^k}$分别为第$k$个注意力头对应的权重和线性变换矩阵,${{\boldsymbol{h}}_i}^\prime $为更新后节点$i$的表示.

经过上述过程,${{G}_1}$中的所有节点向量都得到了更新,最终输出由节点向量构成的二维张量${{\boldsymbol{T}}_{{\text{DDG}}}}$. ${{G}_2}$经过和${{G}_1}$相同的过程,得到张量${{\boldsymbol{T}}_{{\text{CDG}}}}$. ${{G}_1}$${{G}_2}$的聚合过程同时进行,GAT根据${{\boldsymbol{M}}_{{\text{CDG}}}}$$ {{\boldsymbol{f}}_{\text{T}}} $计算${{G}_2}$中各点的注意力系数并进行调整.

2.4. 依赖层聚合

为了考虑PDG各依赖关系的异构性,VulHetG基于注意力机制构建依赖聚合层. 对于节点层聚合产生的2个图张量${{\boldsymbol{T}}_{{\text{DDG}}}}$${{\boldsymbol{T}}_{{\text{CDG}}}}$,尺寸均为($N,D$),其中$N$为节点数,$D$为特征维度. 为了聚合张量${{\boldsymbol{T}}_{{\text{DDG}}}}$${{\boldsymbol{T}}_{{\text{CDG}}}}$,计算${{\boldsymbol{T}}_{{\text{DDG}}}}$${{\boldsymbol{T}}_{{\text{CDG}}}}$中的每个元素${{\boldsymbol{t}}_{{d}}}$${{\boldsymbol{t}}_{{c}}}$间的注意力分数:

$ {{\mathrm{score}}} \left( {{{\boldsymbol{t}}_d},{{\boldsymbol{t}}_c}} \right) = \frac{{{{\boldsymbol{t}}_d} \cdot {{ {{{\boldsymbol{t}}_c}} }^{\text{T}}}}}{{\sqrt D }} . $

式中:${{\boldsymbol{t}}_{{d}}}$${{\boldsymbol{t}}_c}^{\text{T}}$的点积为注意力分数. 利用注意力权重,对${{\boldsymbol{t}}_{{d}}}$进行更新:

$ {{\boldsymbol{t}}_d}^\prime = \sum\limits_{c = 1}^D {{{\mathrm{softmax}}} \left( {{{\mathrm{score}}} \left( {{{\boldsymbol{t}}_d},{{\boldsymbol{t}}_c}} \right)} \right) \cdot {{\boldsymbol{t}}_c}} . $

将softmax归一化的权重矩阵与对应的元素${{\boldsymbol{t}}_c}$相乘得到加权向量,最终得到元素${{\boldsymbol{t}}_d}$的更新${{\boldsymbol{t}}_d}^\prime $. 对于${{\boldsymbol{T}}_{{\text{CDG}}}}$中的元素${{\boldsymbol{t}}_c}$,以相同的方式更新:

$ {{\boldsymbol{t}}_c}^\prime = \sum\limits_{d = 1}^D {{{\mathrm{softmax}}} \left( {{{\mathrm{score}}} \left( {{{\boldsymbol{t}}_c},{{\boldsymbol{t}}_d}} \right)} \right) \cdot {{\boldsymbol{t}}_d}} . $

据此,${{\boldsymbol{T}}_{{\text{DDG}}}}$${{\boldsymbol{T}}_{{\text{CDG}}}}$都对各自的元素进行了更新,得到新的张量表示${{\boldsymbol{T}}_{{\text{DDG}}}}^\prime $${{\boldsymbol{T}}_{{\text{CDG}}}}^\prime $. 通过拼接的方式将二者融合,融入节点层和依赖层异构特征的张量为

$ {\boldsymbol{T}} = {{\boldsymbol{T}}_{{\text{DDG}}}}^\prime \oplus {{\boldsymbol{T}}_{{\text{CDG}}}}^\prime . $

在检测阶段,针对融合张量$ {\boldsymbol{T}}(N,2D) $构建分类任务. 因数据样本包含的节点数不同,导致维度$N$不同,为此计算${\boldsymbol{T}}$的均值,并按顺序裁剪.

$ {{S}} =\left\{\frac{1}{{2D}}\sum\limits_{y = 1}^{2D} {{{{t}}_{xy}}}\right\} {\text{; 1}} \leqslant x \leqslant N .$

$ {\boldsymbol{T'}} = {\boldsymbol{T}}\left[ {{\text{SelectTopN}}\left( {{{S}},n} \right)} \right] .$

式中:${{\boldsymbol{t}}_x}$${\boldsymbol{T}}$中的向量,${t}_{xy}$${{\boldsymbol{t}}_x}$中的元素;${{S}}$为由${{\boldsymbol{t}}_x}$各元素的均值构成的集合;${{\mathrm{SelectTopN}}} $操作用来筛选最大的前$n$个元素;$n$为200,表示将每个图的节点数控制为200.

2.5. 漏洞检测

根据异构图表征的特性,设计有效的漏洞检测模型,具体结构如图2所示.

图 2

图 2   漏洞检测模型的结构

Fig.2   Structure of vulnerability detection model


在节点层,调整部分节点的注意力系数,得到权重矩阵${{\boldsymbol{W'}}_i}$${{\boldsymbol{W}}_i}^{\prime \prime }$$1 \leqslant i \leqslant n$),其中$n$为网络层数. 为了减小传递误差,采用3个注意力头,利用Dropout正则化技术,减小模型对特定样本的依赖. 在依赖层,计算CDG和DDG各自的注意力权重,将二者加权融合. 漏洞检测模块由全连接层和Softmax激活层构成,融合的张量特征在该阶段被深度提取. 采用交叉熵损失函数计算损失.

3. 实验分析

实验采用2个合成数据集和2个真实数据集. 合成数据集包括自建数据集和SySeVR数据集,真实数据集包括Devign和REVEAL[24].

1)自建数据集:从合成漏洞数据库SARD和NVD中提取28 830条C/C++数据样本,共生成15710个PDG样本,包括纯净PDG样本9 887个,10类漏洞PDG样本共5 823个. CWE-ID具有类似树形结构的层次,层次越高表示漏洞场景越广泛. 在第3层挑选发生几率最高的10个CWE-ID进行实验.

2)SySeVR数据集:该数据集基于SARD漏洞库,根据4种漏洞语法规则切片得到. 这4种语法规则分别是AE(算术表达式)、AU(数组使用)、FC(API/库函数调用)、PU(指针操作). 由于语法规则的广泛适应性,该数据集能够覆盖93.6%以上的漏洞场景.

3)真实数据集:REVEAL是从2个开源项目的历史漏洞中构建的数据集,其对内存管理、输入验证相关的漏洞具有较强的覆盖能力. Devign是从4个开源的C语言项目中构建的数据集,结合多种代码表示,提供了全面的漏洞语义信息.

在合成数据集上,采用准确率Acc、精度PF1和召回率R作为评价指标. 在真实项目数据集上,采用误报率FPR和漏报率FNR进行评价.

${\mathrm{ Acc = \frac{{TP+TN}}{{TP+TN+FN+FP}} }}, $

$ P ={\mathrm{ \frac{{TP}}{{TP+FP}} }}, $

$ R = {\mathrm{\frac{{TP}}{{TP+FN}}}} , $

$ {F_1} = 2 \times \frac{{PR}}{{P+R}} , $

$\rm FPR = \frac{{FP}}{{FP+TN}} , $

$ \rm FNR = \frac{{FN}}{{FN+TP}} . $

式中:TP为正样本被正确预测的数量,TN为负样本被正确预测的数量,FP为正样本被错误预测的数量,FN为负样本被错误预测的数量.

3.1. 针对10类漏洞的检测性能

为了验证VulHetG对各类型漏洞的检测能力,在包含10类漏洞的数据集上进行实验验证,结果如表2所示.

表 2   对10类漏洞的检测

Tab.2  Detection of 10 types of vulnerabilities %

CWE编号AccPF1R
CWE-47696.8797.5296.9796.43
CWE-70695.7395.8195.5594.85
CWE-11996.4196.4997.3598.23
CWE-40496.5594.8396.4998.21
CWE-66596.9297.0697.0697.06
CWE-07495.3896.9795.5294.11
CWE-02093.7593.8593.8893.91
CWE-40095.4593.7595.7497.82
CWE-31186.6690.5986.2080.64
CWE-70495.8396.0296.0296.02

新窗口打开| 下载CSV


表2可以看出,涉及内存管理错误的3类漏洞CWE-476、CWE-119和CWE-404的平均Acc和F1最高,达到96.6%和96.9%. 原因是VulHetG从中间代码维护了丰富的内存信息,导致模型对错误的内存操作较敏感. 例如,当发生越界访问时,内存操作指令将错误的参数机器码传递给处理器,返回实际分配之外的地址,并在中间代码中以变量符的形式反映出来,有助于模型学习漏洞特征.

CWE-311和CWE-704是由加密和身份验证引发的漏洞,Acc相差约9.2%. 这是因为CWE-704漏洞的发生与跨平台的类型转换有关,而中间代码的llvm.module.flags内置函数具有定义目标平台数据布局的功能,有利于CWE-704漏洞特征的提取.

从整体来看,VulHetG对10类具有代表性的漏洞平均检测Acc和F1分别达到94.9%和95.1%,这表明VulHetG对涉及内存、输入验证、资源管理和权限管理的常见漏洞普遍具有较高的检测能力.

3.2. 与基线方法的性能比较

资源管理错误漏洞CWE-399和缓冲区溢出漏洞CWE-119在引发方式方面具有一定的代表性. 为了验证VulHetG特征提取方式的有效性,通过实验对比了5种基线模型,结果如表3所示. 表中,DT为单个样本的平均检测时间.

表 3   对CWE-399和CWE-119的检测性能对比

Tab.3  Comparison of detection for CWE-399 and CWE-119

模型CWE-399CWE-119
Acc/%P/%F1/%DT/sAcc/%P/%F1/%DT/s
VulDeePecker71.2975.1871.310.88573.0676.2473.310.891
SySeVR75.9480.5678.241.09279.8084.6279.201.105
mVulSniffer92.7386.3585.901.38095.3293.0988.361.378
FUNDED93.2893.7093.412.15693.8094.4094.382.108
VDoTR94.1294.2794.252.36194.7596.8195.652.258
VulHetG94.0594.1694.622.17396.0196.1395.872.112

新窗口打开| 下载CSV


表3可以看出,VulHetG在2类漏洞上的Acc达到94%和96%,高于双通道模型mVulSniffer[25]. 这可能是因为在中间代码中,变量在每次参与运算时都会附带完整的变量信息,且会用地址指针代替变量作为传参,在多数情况下,模型只需要跨越很短的距离就可以提取依赖关系.

VulHetG模型的检测指标均优于VulDeePecker和SySeVR,这是因为GAT比LSTM和BGRU更适合提取图数据特征. 此外,图表征形式为VulHetG提供了更丰富的结构和依赖信息.

FUNDED和VDoTR比3种基于Token的基线方法检测用时更长,原因是图特征提取更复杂. VulHetG对CWE-399的Acc略低于VDoTR,这是因为张量表征形式的泛化能力更加稳定.

3.3. 在4种语法规则上的性能对比

为了验证VulHetG在异构图数据处理中的有效性,在包含4种漏洞语法规则的数据集上对比5种基线方法,实验结果如表4所示.

表 4   对4种语法规则漏洞的检测性能对比

Tab.4  Detection performance comparison for 4 types of syntax rule vulnerabilities %

模型AEFCAUPU
AccPRAccPRAccPRAccPR
VulDeePecker66.3070.3268.5465.6071.1469.3864.6869.0370.2070.0675.1970.31
SySeVR78.7481.1277.6875.6983.1180.0374.1479.2777.7779.4381.2179.45
mVulSniffer92.6093.0288.3092.7490.6983.1792.1074.7783.1791.5091.0792.69
FUNDED93.8194.4092.1393.7395.7494.3094.2290.6792.4592.4191.8992.62
VDoTR94.0495.1494.0595.1795.3390.1594.3594.7994.6492.0590.4887.83
VulHetG95.1296.2695.1796.0596.1893.4594.3394.6194.7093.1892.1492.45

新窗口打开| 下载CSV


表4可以看出,与VulDeePecker、SySeVR和mVulSniffer方法相比,VulHetG的平均检测准确率分别提升了29.6%、19.3%和2.6%,比FUNDED和VDoTR方法的平均检测精度分别提升了1.6%和0.9%. 这是因为FUNDED和VDoTR基于GGNN网络构建模型,相比于GAT加自注意力机制的模型结构,GGNN更侧重于对长距离依赖关系的捕获. 针对某个漏洞模式中的错误节点,自注意力机制会分配更高的注意力权重,从而强化与该节点相关的依赖路径,在不同漏洞模式下的适应能力更强.

VulHetG对AE和FC漏洞的检测能力略高于AU和PU,证明VulHetG对异构特征明显的漏洞具有更强的识别能力. 原因是AE包含数据依赖,FC包含控制依赖,2种数据存在较强的异构性,而AU和PU存在几乎等量的依赖关系,因此异构程度较低. 从每个数据集的横向对比结果来看,VulHetG较门控单元和GNN更适合于异构特征的提取.

3.4. 在2个真实项目数据集上的性能对比

为了验证VulHetG在真实项目上的泛化能力,在真实项目数据集REVEAL和Devign上对比了方法μVulDeePecker、SySeVR和mVulSniffer. 其中,μVulDeePecker是粗粒度代码切片方法的代表,SySeVR较μVulDeePecker粒度更细,mVulSniffer方法是将粗、细2种粒度切片结合. 不同于上述3种方法,VulHetG利用注意力系数调整来代替切片操作,实验结果如表56所示.

表 5   真实数据集Devign上的检测

Tab.5  Detection on real-world dataset Devign %

模型AccPRF11−FNR1−FPR
μVulDeePecker35.8936.0135.7936.2242.7952.94
SySeVR45.3252.4045.5548.7445.5552.41
mVulSniffer81.2579.2580.3180.2879.2572.25
VulHetG80.4782.8784.7681.0689.1483.87

新窗口打开| 下载CSV


表56可以看出,VulHetG在Devign数据集上的检测准确率达到80.5%,略低于mVulSniffer. 这是因为 mVulSniffer在二次切片时引入函数表达式和条件分支的语法规则,在一定程度上强化了控制流的作用,但对于高度依赖数据流的隐蔽型漏洞,mVulSniffer的提升不如VulHetG明显,例如VulHetG在REVEAL上的Acc和F1较mVulSniffer分别高了8%和11.5%.

VulHetG的平均准确率达到83.9%,较SySeVR和μVulDeePecker分别高了40%和47.3%. 这是因为采用常规预处理方式难以去除真实代码场景中的冗余信息,导致长短时记忆网络难以提取准确的漏洞语义. 相反,VulHetG的特征构建方式产生的噪声更少,且注意力调整机制保留了长距离依赖关系.

3.5. 消融实验

为了验证VulHetG的特征提取方法和模型各部分的有效性,在CWE-119和CWE-399数据集上设计3组消融实验,结果如表7所示.

第1组实验采用不分层的模型策略,利用单层GAT直接聚合PDG节点. 结果显示,与VulHetG相比,不分层的模型的准确率平均下降6.6%. 这是因为单层GAT网络只在节点层传递特征,导致依赖层特征提取不充分. 由于无须对PDG进行分层处理,单个样本的检测时间较VulHetG大幅度减少.

第2组实验将GAT换成GCN,Acc、PF1均有所下降. 原因是GCN通过邻接矩阵和特征矩阵的乘积聚合邻域信息,这种类似图上滤波的操作在处理不同类型的图结构时,无法灵活地适应节点之间的关系变化,导致真实场景下复杂的漏洞模式无法被充分学习.

在第3组实验中,将表征形式换成基于源代码嵌入的PDG,Acc平均下降4.4%. 这是因为原有的底层逻辑描述会被源代码信息干扰,其中的自定义变量、不规则的调用方式都会增加模型学习中的噪声,导致检测效果不如原模型.

4. 结 语

除现有实验之外,本文在低层次漏洞上进行验证并取得了较好的检测效果,表明VulHetG具备提取细微特征进而发掘0day漏洞的潜力. VulHetG与传统的检测模型一样,都缺少0day漏洞标签、通用的数据集和通用的比较方案[26-27],使得模型对0day漏洞的检测效果尚无定论. 另外,VulHetG用于提取特征的数据模态较单一,缺乏对文档、日志、源代码等多模态数据特征的学习,对真实场景的漏洞泛化能力有待提升.

未来将尝试从真实项目中构建通用数据集,并在已有方法的基础上,采用多层注意力机制从多模态数据中提取漏洞特征,通过引入对抗样本辅助训练,获得更强的泛化能力、模型鲁棒性以及0day漏洞检测能力.

参考文献

程靖云, 王布宏, 罗鹏

基于图表示和MHGAT的代码漏洞静态检测方法

[J]. 系统工程与电子技术, 2023, 45 (5): 1535- 1543

[本文引用: 1]

CHENG Jingyun, WANG Buhong, LUO Peng

Code vulnerability static detection method based on graph representation and MHGAT

[J]. Journal of Systems Engineering and Electronics, 2023, 45 (5): 1535- 1543

[本文引用: 1]

田笑, 常继友, 张弛, 等

开源软件缺陷预测方法综述

[J]. 计算机研究与发展, 2023, 60 (7): 1467- 1488

[本文引用: 1]

TIAN Xiao, CHANG Jiyou, ZHANG Chi, et al

Survey of open-source software defect prediction method

[J]. Journal of Computer Research and Development, 2023, 60 (7): 1467- 1488

[本文引用: 1]

MARCELO A, FRANCISCO C, FRANCISCO B. An user configurable clang static analyzer taint checker [C] //Proceedings of the 35th International Conference of the Chilean Computer Science Society. Valparaíso: IEEE, 2016: 10-14.

[本文引用: 1]

YAN Y T, PAN Z L, YU L, et al. Research on the influencing factors of LLVM IR optimization effect [C] //Proceedings of the 3rd International Conference on Information Technology, Big Data and Artificial Intelligence. Chongqing: IEEE 2023: 756-763.

[本文引用: 1]

ZHANG X W, ZHOU Y, TAN S H, et al. Efficient pattern-based static analysis approach via regular-expression rules [C]//Proceedings of the 2023 IEEE International Conference on Software Analysis, Evolution and Reengineering. Taipa: IEEE, 2023: 132-143.

[本文引用: 1]

CHEN D, ZHANG Y D, WEI W, et al

Efficient vulnerability detection based on an optimized rule checking static analysis technique

[J]. Frontiers of Information Technology and Electronic Engineering, 2017, 18 (3): 332- 345

DOI:10.1631/FITEE.1500379      [本文引用: 2]

PEELER H, LI S, SLOSS A N, et al. Optimizing LLVM pass sequences with shackleton: a linear genetic programming framework [C] //Proceedings of the 2022 Genetic and Evolutionary Computation Conference Companion. Boston: ACM, 2022: 578-581.

[本文引用: 1]

MIRSKY Y, MACON G, BROWN M, et al. VulChecker: graph-based vulnerability localization in source code [C] //Proceedings of the 32nd Usenix Security Symposium. Anaheim: ACM, 2023: 6557-6574.

[本文引用: 1]

苏小红, 郑伟宁, 蒋远, 等

基于学习的源代码漏洞检测研究与进展

[J]. 计算机学报, 2024, 47 (2): 337- 374

[本文引用: 1]

SU Xiaohong ZHEN Weining, JIANG Yuan, et al

Research and progress on learning-based source code vulnerability detection

[J]. Chinese Journal of Computers, 2024, 47 (2): 337- 374

[本文引用: 1]

GILPIN L H, BAU D, YUAN B Z, et al. Explaining explanations: an overview of interpretability of machine learning [C] //Proceedings of the 5th International Conference on Data Science and Advanced Analytics. Turin: IEEE, 2018: 80-89.

[本文引用: 1]

CHAKRABORTY S, KRISHNA R, DING Y, et al

Deep learning based vulnerability detection: are we there yet?

[J]. IEEE Transactions on Software Engineering, 2020, 9 (48): 3280- 3296

[本文引用: 1]

LI Z, ZOU D Q, XU S H, et al. VulDeePecker: a deep learning based system for vulnerability detection [C] //Proceedings of the 25th Network and Distributed System Security Symposium. San Diego: IEEE, 2018.

[本文引用: 2]

LI Z, ZOU D Q, XU S H, et al

SySeVR: a framework for using deep learning to detect software vulnerabilities

[J]. IEEE Transactions on Dependable and Secure Computing, 2022, 19 (4): 2244- 2258

DOI:10.1109/TDSC.2021.3051525      [本文引用: 2]

LI Z, ZOU D Q, XU S H, et al

VulDeeLocator: a deep learning-based fine-grained vulnerability detector

[J]. IEEE Transactions on Dependable and Secure Computing, 2022, 19 (4): 2821- 2837

DOI:10.1109/TDSC.2021.3076142      [本文引用: 1]

WU Y M, ZOU D Q, DOU S H, et al. VulCNN: an image inspired scalable vulnerability detection system [C] //Proceedings of the 44th International Conference on Software Engineering, Pittsburgh: ACM, 2022: 2365-2376.

[本文引用: 1]

ZHOU Y Q, LIU S Q, DU X N, et al

Devign: effective vulnerability identification by learning comprehensive program semantics via graph neural networks

[J]. Neural Information Processing Systems, 2019, 2019 (32): 10197- 10207

[本文引用: 1]

WANG H T, YE G X, TANG Z Y, et al

Combining graph-based learning with automated data collection for code vulnerability detection

[J]. IEEE Transactions on Information Forensics and Security, 2021, 2021 (16): 1943- 1958

[本文引用: 2]

FAN Y H, WAN C H, FU C, et al

VDoTR: vulnerability detection based on tensor representation of comprehensive code graphs

[J]. Computers and Security, 2023, 2023 (130): 103247

[本文引用: 2]

ALOMAR E A, ALOMAR S A, MKAOUER M W. On the use of static analysis to engage students with software quality improvement: an experience with PMD [C] //Proceeding of 2023 IEEE/ACM 45th International Conference on Software Engineering: Software Engineering Education and Training.Melbourne: IEEE, 2023: 179-191.

[本文引用: 1]

BARTA B, MANZ G, SIKET I, et al. Challenges of sonarqube plug-in maintenance [C] //Proceedings of the 26th International Conference on Software Analysis, Evolution, and Reengineering. Hangzhou: IEEE, 2019: 574-578.

[本文引用: 1]

PERL H, DECHAND S, SMITH M, et al. VCCFinder: finding potential vulnerabilities in open-source projects to assist code audits [C] //Proceedings of the 22nd ACM Conference on Computer and Communications Security. Denver: ACM, 2015: 426-437.

[本文引用: 1]

ZOU D Q, XU S H, WANG S J, et al

μVulDeePecker: a deep learning-based system for multiclass vulnerability detection

[J]. IEEE Transactions on Dependable and Secure Computing, 2019, 18 (5): 2224- 2236

[本文引用: 1]

FENG Q, FENG C D, HONG W J, et al. Graph neural network-based vulnerability predication [C] //Proceedings of the 2020 IEEE International Conference on Software Maintenance and Evolution. Adelaide: IEEE, 2020: 800-801.

[本文引用: 1]

徐泽鑫, 段立娟, 王文健, 等

基于上下文特征融合的代码漏洞检测方法

[J]. 浙江大学学报: 工学版, 2022, 56 (11): 2260- 2270

[本文引用: 1]

XU Zexin, DUAN Lijuan, WANG Wenjian, et al

Code vulnerability detection method based on contextual feature fusion

[J]. Journal of Zhejiang University: Engineering Science, 2022, 56 (11): 2260- 2270

[本文引用: 1]

张学军, 张奉鹤, 盖继扬, 等

mVulSniffer: 一种多类型源代码漏洞检测方法

[J]. 通信学报, 2023, 44 (9): 149- 160

[本文引用: 1]

ZHANG Xuejun, ZHANG Fenghe, GAI Jiyang, et al

mVulSniffer: a multi-type source code vulnerability sniffer method

[J]. Journal on Communications, 2023, 44 (9): 149- 160

[本文引用: 1]

YANG G

A review of machine learning-based zero-day attack detection: challenges and future directions

[J]. The International Journal for the Computer and Telecommunications Industry, 2023, (198): 175- 185

[本文引用: 1]

ROMERA P B, TORR P. An embarrassingly simple approach to zero-shot learning [C] //Proceedings of the 2020 Conference on Computer Vision and Pattern Recognition. Seattle: IEEE, 2020: 100-109.

[本文引用: 1]

/