SV-GEN:结合大语言模型(LLM)驱动的变量语义分析与图变换算法以进行漏洞检测
作者:刘照辉、杨浩成、谢文杰
《Future Internet》:SV-GEN: Synergizing LLM-Empowered Variable Semantics and Graph Transformers for Vulnerability Detection
Zhaohui Liu,
Haocheng Yang and
Wenjie Xie
【字体:
大
中
小
】
时间:2026年04月28日
来源:Future Internet 3.6
编辑推荐:
摘要 基于深度学习的漏洞检测已经取得了实质性进展,但仍存在两个主要限制。基于序列的方法将源代码线性化,从而削弱了对控制流和数据流依赖关系的明确建模。基于图的方法保留了程序结构,但传统的图神经网络在处理大型代码属性图(CPGs)中的长距离交互时仍存在困难。此外,标准的C
摘要 基于深度学习的漏洞检测已经取得了实质性进展,但仍存在两个主要限制。基于序列的方法将源代码线性化,从而削弱了对控制流和数据流依赖关系的明确建模。基于图的方法保留了程序结构,但传统的图神经网络在处理大型代码属性图(CPGs)中的长距离交互时仍存在困难。此外,标准的CPGs通常缺乏明确的变量语义和安全关键节点的角色,这限制了它们表示与漏洞相关的程序行为的能力。为了解决这些问题,我们提出了SV-GEN,一个结合了大型语言模型驱动的语义增强和混合序列-图学习的漏洞检测框架。SV-GEN的创新之处在于引入了一种语义增强的代码属性图(Sem-CPG),它为传统CPGs添加了变量语义角色和安全导向的节点标签,并将这种表示与结构和序列视图之间的自适应融合机制相结合。具体来说,我们使用大型语言模型作为外部语义注释器来分配变量角色并识别源节点、汇节点和净化节点,然后用GraphTransformer对生成的Sem-CPG进行编码,同时使用GraphCodeBERT对代码序列进行建模。此外,还使用了一个可学习的门控模块来适应性地融合图级和序列级的表示以进行最终预测。在Devign、ReVeal和DiverseVul上的实验表明,SV-GEN在各种基准测试中都能获得竞争性或更优越的整体性能,尤其是在大型且高度不平衡的DiverseVul数据集上表现尤为突出。 1. 引言如今,软件系统几乎支持所有关键领域,从金融交易和医疗保健到工业控制和公共基础设施。因此,软件安全直接关系到经济稳定性和公共安全[1]。漏洞继续以高速度累积,公共安全报告显示每年披露的软件漏洞数量持续增加[2]。仅2023年,就报告了超过25,000个漏洞。一旦被利用,这些漏洞可能导致敏感数据泄露、服务中断和严重的财务损失。例如,2017年的WannaCry勒索软件爆发就是利用了Windows SMB协议中的一个漏洞,感染了全球超过200,000台计算机,造成了数十亿美元的损失。因此,在软件开发过程中尽早检测漏洞对于构建可靠和安全的系统来说是一个基本要求。传统的漏洞检测主要依赖于静态分析、动态分析和手动专家审计[3]。静态分析通过规则匹配和数据流推理来检测可疑模式,但经常会产生大量误报。动态分析可以执行程序并检测运行时缺陷,但其受到代码覆盖范围和计算成本的限制。手动审计可以很准确,但它无法适应现代代码库。随着深度学习的兴起,漏洞检测进入了一个新的阶段。深度模型可以直接从标记数据中学习复杂的漏洞模式,而无需手动设计的规则,并且在效率和泛化能力方面通常表现出色[4]。现有的基于深度学习的漏洞检测方法大致可以分为基于序列的方法和基于图的方法。基于序列的方法将源代码视为文本,对其进行分词,并使用循环网络[5]、LSTMs[6]或 Transformers从生成的令牌序列中学习语义特征[7]。然而,这种表示方式破坏了原始的程序结构,使得难以明确地建模控制流和数据流关系。基于图的方法则将程序转换为结构化图,如抽象语法树(AST)、控制流图(CFG)、数据流图(DFG)或代码属性图(CPGs)[8],然后使用图神经网络来学习结构特征。一个典型的例子是Devign[9],它将AST[10]、CFG和DFG合并成一个复合程序图,并使用门控图神经网络(GGNN)来捕获与漏洞相关的子结构。尽管最近取得了进展,现有的基于深度学习的漏洞检测方法仍存在三个限制:基于序列的编码器中对分散的控制/数据依赖关系的建模不足、基于消息传递的图模型中的长距离传播能力有限,以及传统CPGs中缺乏明确的变量/安全语义。基于序列的方法仍然难以表示复杂的控制传播和数据传播模式。真实的漏洞通常取决于多个分支中的变量赋值,或者从外部输入到危险操作的完整污染传播路径。一旦代码被线性化,这些非线性的执行语义就难以表达。当漏洞条件分布在遥远的代码区域时,模型必须依赖注意力机制来连接它们,这在实践中往往不可靠。基于图的方法保留了程序结构,但传统的图神经网络通过局部消息传递来传播信息,其有效的接收场受到网络深度的限制。更深的网络也会出现过平滑现象,从而削弱了信息性的局部差异[11,12]。在现实的开源项目中,函数大小差异很大,因此生成的代码属性图通常既大又稀疏。标准图神经网络因此在很多跳数上难以传播结构语义,尤其是在依赖长距离交互的漏洞场景中。同时,传统的代码属性图没有充分建模变量语义和安全关键节点。变量节点通常被简化为通用占位符(如VAR1和VAR2),这去除了它们的功能角色,而安全关键节点(如污染源、汇节点和净化器)也没有被明确标记。因此,模型无法关注直接涉及漏洞触发的程序元素。为了解决这些限制,我们提出了SV-GEN,即 Semantic-aware Variable-guided Graph Evolution Network,一个以表示增强为中心的漏洞检测框架,而不是直接基于LLM的端到端预测。关键思想是使用大型语言模型(LLM)作为程序表示构建的语义注释器,而不是作为最终检测器。从一个传统的代码属性图开始,我们引入了一个语义增强的代码属性图(Sem-CPG),该图明确地为图添加了两种与漏洞相关的语义:(1)表征程序逻辑中变量功能角色的变量级语义角色;(2)识别潜在源节点、汇节点和净化器的安全关键节点角色。通过这种方式,生成的图表示保留了传统CPGs的结构完整性,同时揭示了与漏洞形成直接相关的高级语义先验。在这种增强的表示基础上,我们设计了一个混合检测后端,它结合了一个预训练的代码语言模型(CodeLM)和Graph Transformer。序列编码器捕获令牌级和上下文代码语义,而Graph Transformer通过全局注意力模型在Sem-CPG上建模长距离结构依赖关系。然后,一个可学习的门控模块适应性地融合这两种视图,使模型能够根据输入样本的特征平衡序列语义和图结构。因此,SV-GEN的创新不在于单独使用LLM注释、Graph Transformers或多模态融合技术,而在于它们围绕以漏洞为导向的语义图表示的任务导向集成。因此,本文的主要贡献如下:我们提出了Sem-CPG,一种以漏洞为导向的语义程序表示方法,它为传统代码属性图添加了明确的变量角色语义和安全关键节点注释。与传统主要保留结构关系的CPGs不同,Sem-CPG注入了帮助模型关注与漏洞触发密切相关的程序元素和传播模式的语义先验。我们开发了SV-GEN,一个针对Sem-CPG定制的混合序列-图漏洞检测框架。通过结合预训练的代码语言模型、Graph Transformer和自适应门控机制,该框架同时利用了序列代码语义和语义增强程序图中的长距离结构依赖关系。我们在三个公开的漏洞检测基准测试上进行了系统的实证研究,以验证所提出表示和框架的有效性。结果以及消融分析表明,SV-GEN的增益与语义图增强和混合序列-图建模密切相关。 2. 相关工作 2.1. 基于序列表示的深度学习源代码以类似语言的形式表达,因此自然可以从自然语言处理中借用法。在漏洞检测中,代码首先被分割成片段,然后转换成令牌序列,再输入到深度模型中。Li等人首次提出了VulDeePecker[13],它观察到C程序中的漏洞通常发生在库调用周围。因此,它提取了与库调用相关的代码片段,将其命名为Code Gadgets,并使用Word2Vec将其映射成令牌序列。尽管这种设计在预处理时融合了领域知识,但仅关注库调用对于复杂的实际项目来说远远不够。为了获得更符合漏洞特征的代码切片,Li等人后来提出了SySeVR[14],它引入了基于语法的漏洞候选项和基于语义的漏洞候选项。受图像识别的启发,SySeVR根据语法和语义将程序分割成候选片段,然后使用Word2Vec将其转换成令牌序列。为了进一步提高表示效果,Li等人提出了VulDeeLocator[15],它使用编译技术来优化程序表示。它首先从源代码中提取基于语法的漏洞候选项,使用LLVM将其转换为SSA形式的中间表示,从中推导出基于语义的候选项,最后将其映射成向量。除了语法和语义,还可以利用控制信息。Zou等人提出了VulDeePecker[16],它首先将源代码转换为系统依赖图,然后根据该图中库函数的调用关系生成Code Gadgets。在Transformer架构引入后,基于注意力的模型在自然语言处理中迅速占据了主导地位。受益于Transformer的表达能力,Fu等人提出了LineVul[17],它将函数建模为令牌序列,并通过字节对编码将其转换为子词令牌[18]。字节对编码通过重复合并频繁的字节对来提高词汇覆盖率和压缩率。LineVul的研究表明,这种分词策略是其性能的关键因素之一。为了将切片粒度推进到行级别以上,Wu等人提出了UltraVCS[19]。UltraVCS不是以整行作为基本切片单元,而是通过综合考虑关键操作和不安全操作(如敏感API调用、变量赋值和指针偏移)来识别不安全的键变量。然而,该方法仍然严重依赖手动设计的切片规则和基于PDG的依赖关系分析,这意味着其漏洞表示在很大程度上受预定义的启发式规则的限制,而不是显式学习的语义理解。 2.2. 基于图表示的深度学习在编程语言研究中,基于图的程序表示明确地建模了语法、控制依赖关系和数据依赖关系。抽象语法树、控制流图和数据流图构成了结构化代码分析的基础。当它们组合成代码属性图时,为下游的漏洞检测提供了统一的结构视图。与基于序列的模型相比,图表示保留了控制约束、变量传播路径和跨声明的语义关系,因此已成为基于深度学习的漏洞检测的一个主要研究方向。早期的代表作是Devign[9],它将AST、CFG和DFG合并成一个复合程序图,并使用图神经网络来捕获触发漏洞的关键子结构。ReGVD[20]系统地重新审视了图神经架构,指出现有的代码属性图模型容易受到噪声节点的干扰,并提出了具有多尺度跳过连接的更稳定的聚合运算符。IVDetect[21]将图表示与可解释视图结合,使模型可以从控制和数据的角度解释其预测。最近,ANGEL[22]针对大型代码图上的漏洞检测挑战。它引入了一种分层图细化策略来过滤冗余节点并减小图的大小,然后结合GNN和Graph Transformer进行上下文感知的图编码。通过这种方式,ANGEL同时捕获了局部结构信息和长距离依赖关系,成为一个强大的近期基于图的基线。Liu等人进一步提出了Vul-LMGNNs[23],它将预训练的代码语言模型与CPGs上的门控图神经网络结合。为了缓解标准消息传递的局部性,它在平行的学生图神经网络(GNNs)之间引入了在线知识蒸馏,并通过隐式-显式联合训练方案融合了序列和图视图。尽管这种设计改善了语义-结构融合,但它仍然建立在传统的CPG语义和GNN风格的传播之上,使得明确的漏洞导向节点语义建模不足。 2.3. 用于漏洞检测的大型语言模型大型语言模型在自然语言处理方面最近取得了重大进展,它们强大的上下文理解和推理能力引起了人们对软件漏洞检测的日益关注。与传统的深度学习模型相比,大型语言模型提供了更强的语义理解和更好的零样本或小样本泛化能力,这为漏洞分析开辟了新的方向[24]。随着通用模型如GPT[25]、LLaMA[26]和Claude[27]的出现,研究人员开始探索大型语言模型是否可以直接检测漏洞。现有工作主要遵循三个方向。第一个方向是直接使用预训练或微调的大型语言模型进行漏洞检测。这些方法通常将漏洞检测视为分类或序列标注,并依赖于提示、小样本学习或微调,以便模型能够理解程序语义并预测易受攻击的位置或类型。实证研究表明,大型语言模型可以达到合理的功能级性能,并可能检测到传统静态分析工具难以发现的安全模式,但它们在检测粒度、表示鲁棒性和漏洞知识的时效性方面仍面临限制[24]。第二个方向关注专门的调整。例如,SecureFalcon[28]会对Falcon进行安全任务微调,以提高对常见漏洞类别(如Common Weakness Enumeration (CWE)类)的识别能力。也探索了提示工程。GPTScan[29]使用精心设计的提示来指导类似ChatGPT的模型进行零样本或小样本漏洞识别,并在选定的场景中报告了有希望的结果。第三个方向涉及系统设计。许多研究采用检索增强生成来为模型提供相关的外部上下文,而一些最新的系统则在漏洞分析过程中使用多个代理进行协作和迭代优化[24]。
3. 动机示例
本节分析了开源多媒体框架FFmpeg中的一个真实漏洞,即CVE-2023-47470,以说明现有基于深度学习的漏洞检测方法面临的核心挑战,并激发我们方法的设计灵感。图1显示了来自函数ref_pic_list_struct的易受攻击的代码片段。其根本原因是对外部输入缺乏适当的边界检查。变量ref_pic_num是通过get_ue_golomb_long(gb)直接从外部比特流中读取的,因此它是不可信的输入。目标数组rpl->ref_pics[]在头文件结构中被声明为一个静态大小的数组。在代码使用ref_pic_num控制对rpl->ref_pics[i]的重复写入之前,从未检查该值是否超过了数组容量。因此,攻击者可以构造一个大于数组界限的值,导致循环写入rpl->ref_pics[]之外,破坏堆内存,可能触发任意代码执行或崩溃。图1. FFmpeg中的漏洞示例CVE-2023-47470。橙色和红色区域分别表示污染源和污染汇。从语义角度来看,此漏洞的触发路径具有明显的长距离特性。源(ref_pic_num接收用户控制的数据)和汇(ref_pics[i]超出界限处)在代码图中相距很远。路径穿过了多个循环和分支。更重要的是,它与许多与漏洞本身无关的节点混合在一起,例如strp_entry_sign_flag的位移操作和delta_poc_st的条件。这些无关节点引入了大量的语义噪声,容易使模型偏离真正的漏洞传播路径。这一观察激发了两个设计选择:首先,应该明确识别变量角色,以便代码语言模型能够理解不同变量如何促成漏洞触发;其次,应该在程序图中明确标记源和汇信息,以便图编码器收到清晰的安全优先级,并专注于与漏洞形成直接相关的节点和路径。
4. 方法论
本节详细描述了SV-GEN框架,包括任务制定、Sem-CPG的构建以及用于特征聚合和预测的混合后端。
4.1. 概述
SV-GEN是一个通过构建语义丰富的程序图并将预训练的代码语言模型与图变换器相结合来提高性能和泛化能力的漏洞检测框架。如图2所示,该流程包含四个阶段:输入预处理、LLM驱动的Sem-CPG构建、混合特征聚合和最终分类。我们首先对任务进行形式化,然后描述每个阶段。
4.1.1. 问题制定
我们研究函数级别的漏洞检测。给定一个函数,模型预测该函数是否包含安全漏洞。数据集定义为,其中是代码样本,是其标签,1表示易受攻击的样本,0表示非易受攻击的样本。为了利用结构化的程序语义,我们将漏洞检测视为图分类问题。对于每个代码样本,我们构建一个Sem-CPG,其中是节点集。节点特征矩阵为,节点由特征向量表示。边集为,其中每条边表示从源节点到目标节点的类型为的有向依赖关系。学习目标是学习一个分类器,以预测漏洞标签。
4.1.2. SV-GEN工作流程
如图2所示,SV-GEN遵循一个四阶段流程。输入函数首先经过预处理,包括注释删除、标识符规范化和基于静态分析的简化。然后我们使用Joern生成初始代码属性图,并用大型语言模型标注变量语义角色并识别安全关键节点(如源、汇和清洁器),从而得到Sem-CPG。接下来,图变换器对Sem-CPG进行编码,而代码语言模型对自然代码序列进行编码,门控模块将这两种视图融合成统一的表示。最后,分类器输出漏洞概率。
4.2. 语义丰富程序图的构建
图2中的第二阶段通过四个子步骤实现:(1)预处理和变量级语义标注(第4.2.1节),(2)初始CPG构建和代码自然序列(CNS)边插入(第4.2.2节),(3)安全关键节点识别(第4.2.3节),以及(4)语义特征嵌入以获得Sem-CPG节点表示(第4.2.4节)。算法1总结了完整的构建过程。
传统的CPG统一了语法、控制流和数据依赖关系,但它们仍然缺乏漏洞检测所需的语义信息。变量节点通常仅由通用标识符(如VAR1和VAR2)表示,这消除了它们在程序逻辑中的角色。安全关键节点(如污染源、汇和清洁器)也未标记,因此模型难以专注于直接触发漏洞的元素。为了解决这个问题,我们引入了语义丰富的代码属性图(Sem-CPG)。它利用大型语言模型的语义推理能力来标注变量角色和安全关键节点,因此提供了更丰富的面向漏洞的程序表示。如图3所示,在将DiverseVul数据集中的某个数据点转换为Sem-CPG后,其变量名称被修改为包含语义角色的名称,并在图结构中添加了语义标签。
4.2.1. 预处理和变量级语义标注
在许多预处理流程中,变量名称和函数名称被规范化为占位符(如VAR1和FUNC1)。这种设计旨在减少项目特定的词汇偏见,使模型能够专注于结构化的漏洞模式。然而,过度的规范化也会从代码标记中去除有意义的语义线索,削弱表示的语义完整性。因此,我们引入了基于大型语言模型的变量语义标注。其思想是用语义上有意义的角色名称替换原始变量名称,从而使程序保留其原始结构,同时在上下文中恢复变量的功能含义。该过程包括两个阶段:首先通过静态分析简化源代码;然后让大型语言模型推断变量的语义角色。在预处理阶段,我们尽可能保留与行为逻辑相关的程序信息。我们通过常量折叠、死代码消除等相关技术简化源代码,将可分析和信息丰富的陈述集中在更清晰的表示中。这一步减少了冗余结构,同时保留了关键计算和数据流信息,为语言模型提供了更清晰的语义分析输入。为了保持标注过程的稳定性和可解释性,我们使用固定的面向漏洞的变量角色词汇表,包括用户输入、buffer_ptr、buffer_len、size_counter、loop_bound、return_value、status_flag和temp_variable等类别。这些标签仅用于描述变量在上下文中的功能角色,不会改变原始程序逻辑。预处理完成后,将得到的代码片段输入大型语言模型进行语义角色标注。如图4所示,提示模板引导模型从其周围上下文推断每个变量的角色。然后模型用具有角色意识的名称重写变量标识符,同时保留原始的控制流、数据流和语句结构。经过这一步后,变量节点不再是无意义的占位符,而是能够传达程序行为的标识符,从而丰富了后续阶段使用的序列表示。
4.2.2. 程序图构建
我们使用开源的静态分析工具Joern[30]来解析源代码并生成初始代码属性图。代码属性图将几种程序表示集成在一个统一的图中,包括抽象语法树、控制流图、数据流图和控制依赖图。因此,它从多个角度描述了程序行为,即语法、控制依赖关系和数据依赖关系。得到的图包含多种类型的节点,如函数调用、变量和常量,以及异构边,如AST边、CFG边和DFG边。这种结构化的图为后续的面向漏洞的语义增强提供了基础。在初始代码属性图的基础上,我们根据源代码的自然编写顺序添加代码自然序列边。这些边编码了语句的线性执行顺序,补充了纯依赖图所缺失的非结构化语义。因此,最终图同时包含了由AST、CFG、DFG和控制依赖图(CDG)边携带的结构化依赖语义,以及由CNS边携带的线性序列语义。因此,一个函数被表示为一个异构图,其中所有边类型共享相同的节点集,多种语义视图通过异构关系共同表达。
4.2.3. 基于LLM的安全关键节点识别
在大多数现有的基于深度学习的漏洞检测方法中,程序图直接输入图神经网络进行分类。这些方法主要依赖模型从训练数据中隐式学习漏洞模式,但它们没有明确表示安全语义。由于图本身不编码安全角色,模型往往无法区分潜在的数据源、危险操作和清洁逻辑。这限制了漏洞语义的表达能力。受到人类分析师首先识别关键数据流角色然后检查传播路径的启发,我们用显式的安全语义丰富了程序图。我们使用大型语言模型在BasicBlock级别标注安全关键代码块。这种设计选择的动机是,源、汇和清洁器的语义通常由短语句组表示,而不是由孤立标记表示。具体来说,对于图中的每个BasicBlock,大型语言模型分析块内的语句,并确定该块是作为源、汇还是清洁器。当块被识别为这些角色之一时,我们会将预测的标签及其置信度得分附加到节点上。如果块不是安全关键的,则不分配额外的安全标签。图5显示了提示模板。通过这个过程,原本只包含结构化关系的图被扩展了显式的安全语义。由于这些信息直接附加到图节点上,下游的图编码器可以在表示学习过程中同时使用结构化和安全语义。
图5. 基于LLM的污染语义标注的提示模板完整的标记流程以原始代码属性图作为输入,并依次检查所有BasicBlock节点。每个节点都经过语义角色分类和标签附加的处理。输出的是一个经过安全增强的程序图,随后用于漏洞检测。通过明确引入源节点、目标节点和清理节点的信息,模型在图表示学习过程中可以更准确地关注高风险的数据流模式。
4.2.4. Sem-CPG和特征嵌入
在前面的阶段之后,程序图包含了两种类型的语义增强。第一种是变量角色信息,它描述了变量在程序逻辑中的功能角色。第二种是安全角色信息,它识别出安全关键的BasicBlock节点作为源节点、目标节点或清理节点,并附带置信度得分。我们将这些注释与原始代码属性图结合,形成语义增强代码属性图(Sem-CPG)。Sem-CPG的节点集和边集继承自原始代码属性图,而语义标签则作为额外的节点属性被附加。这样,图在保留结构完整性的同时,明确编码了与漏洞相关的语义信息。在语义增强之后,每个节点都被转换为一个密集向量,以便后续的图编码器进行处理。对于每个节点,最终表示由三部分组成:代码-文本嵌入、变量角色嵌入和安全角色嵌入。代码-文本嵌入是通过预训练的代码语言模型对节点相关代码片段进行编码得到的。当节点对应于一个被注释的变量时,添加变量角色嵌入。当节点属于一个安全关键的BasicBlock时,添加安全角色嵌入。对于没有相应标签的节点,我们使用默认嵌入或零向量,以确保所有节点表示都在相同的特征空间中。这三个组成部分随后被连接起来,并投影到一个统一的特征空间中。
4.3. 混合特征聚合与分类
SV-GEN的推理阶段采用了一个混合后端,结合了图变换器(Graph Transformer)和预训练代码语言模型的优势。
4.3.1. 图变换器(Graph Transformer)
SV-GEN的图部分使用图变换器来捕获Sem-CPG中的长距离结构依赖性。给定输入图的节点特征矩阵,图变换器应用多层自注意力机制,使得每个节点能够与超出局部消息传递范围的结构相关节点进行交互。图变换器是一个基于自注意力的图编码器,它解决了传统图神经网络在处理长距离依赖性方面的局限性。给定一个程序图及其节点特征矩阵,图变换器应用多层自注意力聚合。在第l层,注意力计算定义为...
4.3.2. 用于序列语义特征的CodeLM
自然代码序列由预训练的代码语言模型(如CodeBERT [31]或GraphCodeBERT [32])进行编码。我们设计了一个灵活且可替换的架构,可以根据不同类型的代码选择合适的语言模型。由于这些模型是在大型代码语料库上预训练的,它们能够提供强大的源代码语义表示。给定令牌序列,代码语言模型生成...
4.3.3. 门控融合(Gating Fusion)
图嵌入强调结构信息和长距离依赖性,而序列嵌入则捕捉源代码中的语义细节。不同类型的漏洞可能在不同程度上依赖于这两种视图。由复杂数据传播驱动的漏洞可能更依赖于图结构,而由语义误用主导的漏洞可能更依赖于序列代码语义。因此,我们引入了一个可学习的门控网络,来适应性平衡这两种表示...
4.4. 联合优化
在训练过程中,我们联合优化图变换器、代码语言模型的适配层(如果启用了微调)以及门控网络。总损失定义为...
5. 实验评估
为了全面评估SV-GEN的有效性,我们在三个广泛使用的公共漏洞检测基准测试上进行了系统的实验。首先描述研究问题、数据集、基线、评估指标和实现细节,然后分析实验结果。
5.1. 研究问题
我们的研究涵盖了四个研究问题。RQ1探讨SV-GEN在漏洞检测方面是否优于现有基线,从而评估该框架的整体有效性。RQ2检查Sem-CPG是否比标准的代码属性图更有效,揭示了变量语义角色注释和安全关键节点标记的贡献。RQ3研究了SV-GEN中主要组件的效果,包括图变换器、代码语言模型和门控融合模块。RQ4评估SV-GEN对不同漏洞类型的敏感性以及其收益在不同CWE类型上的稳定性。
5.2. 数据集
我们在三个广泛使用的实际世界基准数据集上评估SV-GEN,这些数据集涵盖了多种漏洞类型和不同的数据集规模。
Devign是由Zhou等人[9]引入的一个经典的函数级漏洞检测基准测试。它仍然是该领域被引用最多的数据集之一。该数据集来自四个代表性的大型开源C项目,即Linux Kernel、QEMU、Wireshark和FFmpeg。作者通过自动化脚本检索与安全相关的提交,并结合手动验证进行收集。
ReVeal [33]是另一个大规模的函数级漏洞数据集,包含来自多个开源项目的C和C++代码。它是通过从GitHub自动收集,并结合静态分析和手动验证构建的。该数据集包含多种漏洞类型,包括缓冲区溢出和格式字符串漏洞,因此具有很强的多样性和实际相关性。
DiverseVul [34]是一个较新的数据集,旨在解决早期基准测试中漏洞类型的不平衡问题。它包含了来自多个大型开源项目的更多样化的漏洞模式和编码风格,这使得它成为评估模型鲁棒性的一个具有挑战性的基准测试。
5.3. 基线
为了全面评估SV-GEN的性能,我们将其与八个代表性的基线进行了比较,这些基线涵盖了主流的漏洞检测技术,包括静态分析工具、基于序列的方法和基于图的方法。
(1) Flawfinder [35]是一个经典的开源静态分析工具。它通过内置的漏洞模式数据库扫描C和C++源代码中的潜在安全缺陷。该工具通过词汇匹配规则识别危险函数调用(如strcpy和sprintf),并按风险等级对匹配结果进行排序。Flawfinder不需要训练,适合快速扫描,但其检测能力受到预定义规则覆盖范围的限制,经常产生误报和漏报。
(2) Devign [9]是一种早期的基于图神经网络的漏洞检测方法。它是第一个将AST、CFG和DFG融合成复合程序图,然后使用带门控的图神经网络学习漏洞模式的工具。Devign验证了结构图信息在漏洞检测中的重要性,仍然是该领域的一个经典基线。
(3) GraphCodeBERT [32]是微软提出的一个预训练代码语言模型。它通过数据流信息扩展了CodeBERT的功能。通过两个预训练任务——边预测和节点对齐,模型学习了代码和变量之间的语义表示。在漏洞检测中,GraphCodeBERT对代码序列进行编码,并通过[CLS]令牌的输出表示进行二元分类。
(4) LineVul [17]是一种基于Transformer的函数级漏洞检测方法。它使用预训练的RoBERTa模型对代码序列进行编码。该方法采用字节对编码来处理代码令牌,并使用注意力机制支持行级漏洞定位。LineVul在大型数据集上展示了强大的检测和定位性能。
(5) ReGVD [20]是一种最新的基于图神经网络的漏洞检测方法,系统地重新审视了图表示和消息传递。它引入了更稳定的残差聚合操作符和多尺度跳跃连接,有效缓解了图神经网络中的过度平滑问题。ReGVD在多个基准数据集上表现出有竞争力的性能。
(6) CFExplainer [36]是一种基于图神经网络的漏洞检测方法,具有反事实解释功能。在基于图的漏洞分类的基础上,它生成反事实图来解释模型预测,并识别最强烈影响最终决策的子图结构。CFExplainer通过解释引导的特征选择提高了可解释性,并增强了检测性能。
(7) DeepWuKong [37]是一种基于程序切片和深度学习的漏洞检测方法。它首先通过程序依赖图提取与安全相关的代码片段,然后使用图神经网络学习结构特征进行分类。通过专注于安全关键的程序片段,DeepWuKong减少了无关代码的干扰,提高了检测的针对性。
(8) ANGEL [22]是一种针对大型代码图的最新基于图的漏洞检测方法。它通过两个关键组件来解决这一问题:一个分层图 refinement模块逐步移除不重要的节点以简化输入图;一个基于上下文的图编码模块,结合GNN和图变换器来捕捉局部结构交互和长距离依赖性。通过减少图冗余同时保留与漏洞相关的上下文,ANGEL在公共漏洞检测基准测试上取得了出色的性能,因此成为一个有竞争力的最新基线。
5.4. 评估指标
为了全面评估检测性能,我们使用了以下四个广泛采用的指标:
(1) 准确率(Accuracy)[38]。准确率测量所有样本中正确分类样本的比例。定义为...
准确率是最直观的指标,但在类别分布不平衡时可能会产生误导。
(2) 精确度(Precision)[38]。精确度测量预测为漏洞的样本中实际是漏洞的比例。定义为... 在漏洞检测中,精确度反映了误报率。较高的精确度意味着模型在避免将良性代码误分类为漏洞方面表现更好。
(3) 召回率(Recall)[38]。召回率测量模型检测到的真正是漏洞的样本比例。定义为... 召回率在漏洞检测中尤为重要,因为遗漏的漏洞可能导致严重的安全风险。较高的召回率意味着模型发现了更多的潜在漏洞。
(4) F1分数(F1 score)[38]。F1分数是精确度和召回率的调和平均值。它综合考虑了精确度和召回率,定义为... 在类别不平衡的情况下,F1分数提供了对模型性能的更客观总结,因此是漏洞检测中最常用的指标之一。
5.5. SV-GEN的实现
5.5.1. 实验环境和设置
我们使用Python 3.11.14和PyTorch 2.4.0实现SV-GEN。所有实验都在配备了NVIDIA Tesla V100 32GB GPU、NVIDIA驱动程序525.105.17和CUDA 11.8的服务器上进行。在Sem-CPG构建过程中,变量角色注释和安全关键节点标记由DeepSeek-V3 [39]完成,它在成本和质量之间提供了实际的平衡。在混合后端中,图变换器编码Sem-CPG,而GraphCodeBERT作为预训练的序列编码器。他们的输出通过一个可学习的门控网络融合后,然后传递给分类器。我们使用AdamW作为优化器,学习率设置为某个值,并在训练开始时进行线性热身以稳定优化过程。为了避免过拟合,我们根据验证F1分数来使用提前停止策略。当验证F1分数连续十个周期没有改进时,训练将停止,并将模型恢复到最佳检查点。对于每个基线,我们尽可能严格地复现公开可用的实现,并遵循原始论文中描述的超参数设置。5.5.2 数据划分对于每个数据集,我们随机将样本分成训练集、验证集和测试集,比例为8:1:1。我们将随机种子固定为42以确保可重复性。为了减少数据泄露,我们确保来自同一项目的代码样本不会同时出现在训练集和测试集中。表2中报告的所有指标都是在8:1:1划分后的保留测试集上计算得出的,而不是从表1中的完整数据集统计信息中得出的。此外,对于Flawfinder基线,我们使用的是命令行版本2.0.19。我们观察到在一小部分基准实例上偶尔会出现样本级解析或报告的不稳定性。为了确保公平性,我们在相同的划分设置下对所有运行应用了一致的指标聚合协议。表1. 数据集统计信息。表2. SV-GEN与基线方法在三个数据集上的性能比较(在保留的测试集上评估)。5.6 结果与分析 5.6.1 总体性能(RQ1)为了评估SV-GEN的总体性能,我们将其与八个基线在三个基准数据集上进行比较。表2报告了保留测试集上的准确率、精确度、召回率和F1分数。表2揭示了几个重要发现。SV-GEN在所有三个基准测试中都表现出稳定的竞争优势,特别是在DiverseVul上获得了最佳成绩,它在所有四个指标上都取得了最高分。这一结果很重要,因为DiverseVul是最大的基准数据集,并且包含了最严重的类不平衡,这使得它更接近实际部署场景。与Flawfinder的对比突显了数据驱动模型的普遍优势。Flawfinder依赖于预定义的模式集,因此在所有数据集上的表现都较差。例如,在DiverseVul上,其精确度和召回率仅为12.53%和12.84%,这意味着它漏掉了许多真正的漏洞,同时产生了许多误报。相比之下,SV-GEN直接从标记数据中学习漏洞语义,因此实现了更高的覆盖率和可靠性。与基于序列的基线相比,SV-GEN也显示出明显的优势。GraphCodeBERT和LineVul是两种强大的基于令牌序列建模的代表,但它们仍然将非线性程序行为压缩为线性令牌流。在DiverseVul上,SV-GEN的F1分数比LineVul提高了4.70个百分点,比GraphCodeBERT提高了6.39个百分点。在ReVeal上,SV-GEN的召回率达到了41.50%,比GraphCodeBERT高出4.63个百分点,比LineVul高出3.27个百分点。这些增益表明,当漏洞条件依赖于分散的控制和数据依赖性时,显式的结构建模仍然很重要。与基于图的基线的比较同样具有信息量。Devign直接将图神经网络应用于复合代码图,在所有三个数据集上都落后于SV-GEN。ReGVD通过更好的聚合和跳过连接改进了图学习,但其在ReVeal上的召回率仍限制在35.46%,这表明其预测行为更为保守。CFExplainer和DeepWuKong分别提高了可解释性和切片质量,但它们仍然无法达到SV-GEN的总体性能。ANGEL是我们比较中最强的基于图的基线,在Devign上取得了最好的F1分数。然而,SV-GEN在ReVeal和DiverseVul上超过了ANGEL,且在DiverseVul上的优势非常显著。这一模式表明,随着图的大小增加和漏洞分布的多样化,Graph Transformer的全局自注意力和Sem-CPG中的显式安全先验变得越来越有用。在十二种评估设置中,即在三个数据集上的四个指标上,SV-GEN在八种设置中取得了最佳结果。总体而言,该框架不仅在平均性能上具有竞争力,而且在不同的数据集和指标上都具有鲁棒性。5.6.2 图表示的有效性(RQ2)这个实验评估了Sem-CPG与简单图表示相比是否提高了漏洞检测能力。为了隔离图表示的影响,我们保持模型架构和超参数不变,只改变输入图。因为DiverseVul是最大的数据集,且漏洞比例最低(为5.73%),所以它是衡量表示质量最敏感的基准。因此,我们在DiverseVul上进行了这项实验。我们比较了三种图变体:一种结合了AST、CFG、DFG和CDG的标准代码属性图;一种增加了代码自然序列边的增强图;以及进一步添加了变量语义角色注释和污点标签的完整Sem-CPG。图6总结了准确率、精确度、召回率和F1分数的结果。图6显示Sem-CPG在所有四个指标上都取得了最佳结果。准确率的差异相对较小,分别为CPG的90.58%、CPG+CNS的90.94%和Sem-CPG的92.53%。这是预期之中的,因为非漏洞样本占DiverseVul的94.27%,在这种不平衡的情况下准确率的信息量较低。精确度、召回率和F1分数提供了更清晰的情况。Sem-CPG的精确率达到31.59%,比CPG提高了3.85个百分点。其召回率为23.83%,比CPG高出6.65个百分点。F1分数从CPG的21.22%提高到CPG+CNS的22.92%,再提高到Sem-CPG的27.17%,总共有5.95个百分点的增益。两个增强阶段的增益呈现不同的模式。添加CNS边将F1分数从21.22%提高到22.92%,这表明自然序列顺序补充了结构依赖信息。当漏洞触发依赖于在源代码顺序上接近但在依赖图中连接的不强时,这一点特别有帮助。更大的增益来自添加语义角色和安全标签。变量角色注释将通用标识符转换为功能实体,如输入变量、缓冲区和循环计数器,这有助于模型在节点级别理解程序行为。安全标签提供了关于来源、汇集点和清除器的显式先验,这引导Graph Transformer指向风险区域和传播路径。这两种信号是互补的,因为一个增强了局部语义的可区分性,另一个识别出对安全敏感的图区域。总体而言,结果表明Sem-CPG为漏洞检测提供了比标准图表示更强的基础。通过在图上首先添加自然序列语义,然后添加LLM驱动的安全语义,它为大型和稀疏的现实世界基准提供了更具辨别力的程序表示。5.6.3 消融研究(RQ3)为了研究SV-GEN中主要组件的贡献,我们从三个角度进行了消融研究:不同大型语言模型对Sem-CPG标记质量的影响、图编码器架构的影响以及预训练代码语言模型?影响。所有实验都在DiverseVul上进行,它的规模和不平衡性使得组件差异更容易观察到。除非另有说明,否则所有其余模块和超参数保持不变。我们首先研究大型语言模型的选择如何影响语义标记的质量。由于Sem-CPG依赖于大型语言模型来标注变量角色和安全关键节点,因此这种标注的质量直接影响到下游的检测。我们比较了Qwen2.5-Coder-7B [40]、Qwen3-Coder-30B-A3B和DeepSeek-V3 [39]。然后将得到的Sem-CPGs输入到相同的后端。表3报告了结果。表3. 不同大型语言模型对DiverseVul上Sem-CPG标记质量的影响。DeepSeek-V3的表现最好,准确率达到93.53%,F1分数达到27.17%。这一结果与预期一致,即更强的代码模型提供了更好的语义推理。Qwen3-Coder-30B-A3B将F1分数提高了1.55个百分点,而DeepSeek-V3进一步将F1分数提高了3.63个百分点。这一模式表明,更高质量的语义标注产生了明显的下游效益。对于简单的案例,如清晰的用户输入或明显的缓冲区操作,即使是较小的模型通常也能产生正确的标签。更强的模型主要帮助处理模糊的案例,例如,当一个变量可以被合理地解释为循环计数器或数组索引,或者当函数调用可能作为清除器或可能不作为清除器时。召回率的差异尤其显著,这表明更好的语义标注有助于减少漏掉的漏洞。接下来我们研究图编码器。在默认的SV-GEN设置中,图分支使用Graph Transformer。我们用门控图神经网络和图注意力网络(GAT)替换了它,并考虑了没有图编码器的设置,记为w/o GNN,在这种设置下模型仅依赖于序列特征。所有图编码器使用相同的三层深度,其余设置保持不变。表4报告了结果。表4. 不同图编码器对DiverseVul上检测性能的影响。Graph Transformer在所有四个指标上表现最佳,F1分数达到27.17%。移除图分支后,F1分数降低到20.98%,这证实了结构信息对于漏洞检测至关重要。GAT在F1分数上虽然比无图设置有所提高,但仍落后于Graph Transformer 5.21个百分点。尽管GAT使用了注意力机制,但它只关注局部邻域,没有有效利用Sem-CPG的整个异质性。GGNN的表现优于GAT,因为它的门控更新机制在多个传播步骤中积累信息,但其有效接受域仍然受到网络深度的限制。Graph Transformer通过允许每个节点全局关注来避免这一瓶颈,这在漏洞依赖于长传播路径和跨分支关系时特别有用。最后,我们研究序列编码器。我们用CodeBERT替换了默认的GraphCodeBERT,并考虑了没有代码语言模型的设置,记为w/o CodeLM,在这种设置下模型仅依赖于图分支。两种代码语言模型都在相同的学习计划下进行了微调。表5报告了结果。表5. 不同预训练代码语言模型对DiverseVul的影响。移除序列编码器后,F1分数从27.17%降低到22.01%,这表明即使在存在图分支的情况下,源代码级语义特征仍然重要。GraphCodeBERT在F1分数上比CodeBERT高出3.76个百分点。可能的原因是GraphCodeBERT使用了如边预测和节点对齐等数据流感知的目标进行预训练,而CodeBERT仅关注掩码语言建模和替换令牌检测。因此,在GraphCodeBERT预训练期间学习到的结构先验更有效地补充了Sem-CPG。总的来说,消融研究表明SV-GEN的主要组件提供了互补的增益。Graph Transformer提供了最强的图表示,GraphCodeBERT提供了比通用代码语言模型更丰富的序列语义,而更强大的大型语言模型为Sem-CPG提供了更好的语义注释。移除这些组件中的任何一个都会导致性能明显下降。5.6.4 对漏洞类型的敏感性(RQ4)为了进一步研究SV-GEN在不同漏洞模式上的表现,我们将SV-GEN与GraphCodeBERT在DiverseVul测试集中最常见的十个CWE类别上进行比较。这些类别涵盖了几个安全维度,包括内存边界违规、资源生命周期错误、输入验证问题和并发缺陷。使用GraphCodeBERT作为参考,因为它是DiverseVul上最强的基于序列的基线,并且已经包含了数据流感知的预训练。因此,这种比较突显了语义图增强和混合模型的额外价值。图7显示SV-GEN在所有十个漏洞类别上都优于GraphCodeBERT,但差距相当大,从CWE-416的11.83个百分点到CWE-200的3.74个百分点不等。这种变化与每个漏洞类型的语义特征以及我们方法的设计密切相关。图7. GraphCodeBERT和SV-GEN在DiverseVul上的逐CWE比较。SV-GEN在具有显式数据传播路径的漏洞上取得了最大的增益。在CWE-416(使用后释放)上,F1分数提高了11.83个百分点。这个类别依赖于一个来源,即内存释放操作,以及一个汇,即悬空指针的后续使用,这两者通常被多个函数调用和分支分隔开。在Sem-CPG中,这些关键点可以被显式标记,即使它们在图中相隔很远,图变换器也能将它们连接起来。CWE-787(越界写入)和CWE-125(越界读取)遵循类似的模式,分别获得了10.63%和9.25%的提升。这些漏洞依赖于从外部输入到缓冲区访问的传播,在这种设置中显式的源-汇标签尤其有效。CWE-362(竞争条件)也显示出10.82%的显著提升。尽管这一类别的绝对F1分数不是最高的,但改进是实质性的,因为竞争条件通常涉及分散的共享状态访问。变量角色注释帮助模型更准确地识别共享资源,而图变换器则捕捉了远距离控制路径之间的关系。SV-GEN在变量语义重要的类别上也稳步提升。CWE-119(通用缓冲区边界错误)和CWE-476(空指针解引用)分别获得了7.86%和7.46%的提升。检测这些漏洞需要模型区分缓冲区、指针和控制变量,并理解在可行路径上是否存在相关检查。Sem-CPG通过将匿名标识符转换为具有语义意义的程序实体来提供帮助。CWE-20(不正确的输入验证)提升了6.93%,这进一步证实了显式源标签有助于模型跟踪未经检查的输入向危险操作的传播。在CWE-200(信息泄露)和CWE-401(内存泄漏)这两个类别中,提升幅度较小,分别为3.74%和4.45%。这种模式也是可以理解的。信息泄露往往不太依赖于明确的污染路径,而更多依赖于更广泛的程序意图,例如错误消息是否泄露了内部状态或日志语句是否输出了敏感字段。这类情况需要对设计意图和策略有更高层次的理解,而这并不是源-汇风格的图增强所能完全捕捉到的。相比之下,内存泄漏检测依赖于路径的完整性。模型必须推断分配的内存是否在所有相关执行路径上都被释放,这仅通过局部语义标签是难以表达的。总体而言,SV-GEN在数据流密集型漏洞类别上特别有效,其中显式的语义标记和全局图注意力与问题的结构很好地对齐。尽管提升幅度较小,但在需要更广泛意图理解或路径完整推理的漏洞类型上仍然一致,这为未来的工作指明了有希望的方向。
5.7. 运行时效率
为了进一步评估SV-GEN的实际效率,我们对三个基准数据集中的随机采样测试函数进行了额外的运行时分析。具体来说,我们从每个数据集中随机选择了300个函数,共计900个函数进行运行时测量。所有实验都在第5.5.1节描述的相同硬件和软件环境下进行。由于SV-GEN中的语义增强阶段依赖于对DeepSeek-V3的调用,我们分别报告了每个主要组件的平均函数运行时。表6展示了运行时分解情况。平均预处理时间仅为每个函数1毫秒。基于Joern的图构建加上CNS边构建平均需要300毫秒。混合后端前向传递,包括图变换器、GraphCodeBERT和基于门的融合,每个函数只需要4毫秒。相比之下,主要的开销来自两个LLM驱动的语义增强阶段。变量语义角色注释平均需要5.62秒,而安全关键节点标记(即源/汇/清洗器的识别)需要7.86秒。所有测量组件的总和约为每个函数13.79秒。
5.8. LLM基础语义标签质量的直接验证
为了直接评估Sem-CPG中使用的基于LLM的语义增强的可靠性,我们对三个基准数据集的测试分区中随机抽取的一个子集进行了集中的手动验证研究。具体来说,我们总共抽取了30个函数,包括来自Devign的10个函数、ReVeal的10个函数和DiverseVul的10个函数。这个实验旨在为LLM生成的语义标签的质量提供直接证据,补充之前实验中报告的下游检测结果。我们评估了Sem-CPG构建过程中使用的两种标记任务。第一项任务是变量语义角色标记,其中LLM根据代码中的上下文使用为变量分配语义角色名称。第二项任务是安全关键节点标记,其中LLM将每个BasicBlock分类为四个类别之一:源、汇、清洗器或无。在这个实验中,使用DeepSeek-V3作为标记模型,与SV-GEN的主要实现一致。为了获得参考注释,两名注释者独立审查了抽取的函数并根据主要方法中使用的一致语义标准分配了标签。然后由第三位裁决者解决分歧,并将裁决结果视为黄金标准。我们将DeepSeek-V3生成的标签與此黄金标准进行比较。由于这两项任务可能涉及类别不平衡,我们使用Macro-F1作为评估指标。表7总结了手动验证结果。DeepSeek-V3在变量语义角色标记上的Macro-F1得分为76.21,在安全关键节点标记上的得分为82.94。这些结果直接证明了LLM生成的语义注释与人类判断相当一致。因此,Sem-CPG中使用的语义增强策略不仅得到了下游漏洞检测性能的支持,也得到了对样本实例的直接手动验证的支持。
6. 结论
本文介绍了SV-GEN,这是一个用于函数级源代码漏洞检测的新框架。其核心思想是使用大语言模型驱动的语义增强来弥补标准CPG有限的漏洞语义,然后将全局结构建模与时序语义建模结合在一个混合后端中。我们设计了Sem-CPG作为统一的程序表示。从一个标准的代码属性图开始,我们使用大语言模型为变量节点分配语义角色,以便恢复被标识符规范化移除的功能含义。我们还识别安全关键节点并附加源、汇和清洗器标签,以便直接标记出涉及漏洞触发的程序元素。在Sem-CPG之上,我们使用图变换器来编码全局结构依赖性,并使用GraphCodeBERT来编码序列代码语义,并通过一个可学习的门控机制结合这两种视图来预测漏洞概率。在Devign、ReVeal和DiverseVul上的广泛实验表明,SV-GEN在大多数设置中均优于强大的基线,这证实了该框架的有效性。进一步分析显示,每个主要组件都对最终性能有积极贡献。图变换器模型比传统的图神经架构更有效地建模了长距离依赖性;更强的大语言模型产生了更高质量的语义注释,尽管边际收益逐渐减小。每CWE的分析进一步表明,SV-GEN在数据流密集型漏洞(如使用后释放和越界写入)上特别有效,而需要更高层次意图理解或路径完整推理的类别仍然更具挑战性。
未来的工作有几个重要的方向。首先,当前的Sem-CPG主要通过变量语义角色和源/汇/清洗器标签来增强标准CPG。一个自然的下一步是结合更丰富的程序逻辑信息,如过程间依赖性、API使用约束、控制优势模式,甚至是轻量级的符号或动态证据,以便表示能够更好地捕捉那些依赖于长时间执行上下文或隐式语义条件的漏洞。其次,尽管SV-GEN目前执行的是函数级预测,但实际的安全审计通常需要更细粒度的输出。因此,我们计划将框架从粗粒度检测扩展到语句级别或行级别的漏洞定位,并通过识别最支持每个预测的关键节点、边和语义注释来进一步提高可解释性。第三,当前的流水线在基于LLM的注释阶段仍然会产生不可忽视的开销。未来的工作将研究更高效的语义增强策略,如缓存注释的重用、仅对可疑区域的选择性注释以及精简或本地的轻量级注释器,以改进在大规模真实代码库中的可扩展性。最后,我们将在更现实的设置下评估SV-GEN的泛化能力,包括跨项目和跨数据集的迁移、混合语言仓库以及工业连续分析场景,以进一步评估其鲁棒性和实际适用性。
生物通微信公众号
生物通新浪微博
今日动态 |
人才市场 |
新技术专栏 |
中国科学人 |
云展台 |
BioHot |
云讲堂直播 |
会展中心 |
特价专栏 |
技术快讯 |
免费试用
版权所有 生物通
Copyright© eBiotrade.com, All Rights Reserved
联系信箱:
粤ICP备09063491号