《SoftwareX》:VulnSight: Semantics-guided verification of known vulnerabilities in open-source software
编辑推荐:
VulnSight是一个用于验证目标软件版本中是否存在已知漏洞的软件框架。现有漏洞数据库与检测工具通常依赖元数据或语法级补丁匹配,在重构、文件迁移与长期代码演化条件下可能失效。给定漏洞描述、补丁、易受攻击与已修复参考快照以及目标版本,VulnSight重建两种
VulnSight是一个用于验证目标软件版本中是否存在已知漏洞的软件框架。现有漏洞数据库与检测工具通常依赖元数据或语法级补丁匹配,在重构、文件迁移与长期代码演化条件下可能失效。给定漏洞描述、补丁、易受攻击与已修复参考快照以及目标版本,VulnSight重建两种语义抽象——VulnPattern与SafePattern,识别目标侧相关代码区域,并执行由大语言模型(LLM)引导的语义验证。该框架返回具有证据支持且推理可解释的判定结论。VulnSight为Python、Java与C/C++项目提供语言感知的预处理,并在Python与Java上开展系统性评估,在C/C++上开展初步的基于案例的验证。
现代软件高度依赖开源第三方组件,已知漏洞检测因而依赖OSV与GitHub Security Advisories中的受影响版本范围,这些范围驱动自动化告警与修复决策,但不准确且缺乏解释的范围会导致误检与修复延迟。传统验证方法难以应对函数重命名、API变更、文件迁移、重构与调用图重构,这些变化使补丁位置、漏洞根因位置与目标版本中相应实现之间缺乏稳定映射。主流漏洞数据库与检测工具通常从CPE记录、文本公告或补丁派生签名推断受影响版本范围,将受影响版本判定简化为对公告描述或补丁差异的表面匹配;现有漏洞存在性验证方法多采用补丁签名匹配、代码克隆检测或语法相似性分析等类似前提,当项目经历重构、API变更或文件迁移等代码演化时可靠性显著下降。在代码演化条件下验证已知漏洞的关键挑战在于提取漏洞的根因语义及其修复语义:漏洞是否存在最终不仅取决于表面代码相似性,还取决于目标版本是否满足漏洞触发条件或修复引入的安全约束。例如CVE-2022-42966(Cleo中的ReDoS漏洞)的触发条件依赖表格渲染逻辑中的正则表达式解析,部分历史版本缺少相关正则表达式与调用路径因而不满足触发条件;CVE-2023-43804(urllib3中由跨主机重定向导致的Cookie泄漏漏洞)的修复引入在跨主机重定向时移除Cookie头的防御逻辑,部分历史版本因缺少该防御逻辑实现而仍然脆弱。这些差异表明,可靠的已知漏洞验证必须同时判定目标版本是否实例化漏洞根因语义以及是否满足修复语义。
为解决该挑战,研究人员提出VulnSight,一个语义驱动的框架,用于验证目标软件版本中是否存在已知漏洞。为捕获漏洞根因语义与修复引入的行为,VulnSight将脆弱实现及其对应修复逻辑的高层行为抽象为两种显式语义表示:VulnPattern编码与脆弱状态相关的因果机制与触发条件,SafePattern捕获与安全状态相关的功能约束与防御行为。VulnSight利用大语言模型(LLM)判定目标代码包含脆弱语义模式还是安全语义模式;通过匹配语义模式而非仅依赖语法相似性,VulnSight被设计为在重构、架构变更与跨版本差异中降低对精确补丁位置对应关系的依赖,为跨多样软件生态判定漏洞存在性提供可解释依据。其贡献包括:一是语义重建模块,从漏洞相关补丁、脆弱代码、修复代码与漏洞描述中推导人类可读的漏洞语义与修复语义,刻画底层漏洞机制、触发条件及修复引入的条件;二是模块化验证工作流,用于判定目标代码是否包含已知漏洞,支持结构化预处理、多编程语言与可解释证据,从而促进下游漏洞分析与维护任务。
VulnSight是面向演化中开源项目的已知漏洞验证框架,给定描述、补丁、脆弱与修复快照及目标版本,判定是否存在脆弱行为或修复约束,其为具有模块化、语言感知预处理的Python工作流。软件架构分三阶段:首先从参考产物重建VulnPattern与SafePattern;其次检索结构与语义相关的目标代码;第三由LLM将证据与两种模式比较并返回可解释结果。从用户视角,框架作为端到端验证流水线运行,输入为漏洞产物与待检查的目标项目版本,输出包括漏洞判定、支持证据与置信度估计,可互换的预处理与调用图后端支持多语言。VulnSight为模型可配置而非绑定单一专有LLM,LLM后端通过配置文件指定,记录模型名称、API端点、解码参数、重试设置与提示模板标识;本文经验用例采用DeepSeek-R1-0528作为默认后端,因其在模型比较中取得最佳总体准确率,用户可在不修改预处理或验证模块的情况下替换为其他具备代码能力的聊天式LLM。提示模板随源代码发布,对应主要验证阶段,包括语义重建、目标侧候选补充、漏洞实例化检查、修复实例化检查与最终一致性检查。为可复现与可检查,VulnSight存储每次运行的完整验证上下文,包括漏洞标识、目标版本、选定候选块、重建的VulnPattern与SafePattern、提示模板版本、模型名称、解码参数、原始LLM响应、解析决策、置信度值与重试次数;失败或不可解析调用最多重试三次,全部失败则标记为未解决。所报告置信度为辅助一致性估计而非校准概率:当漏洞实例化检查、修复实例化检查与最终一致性检查同具体目标侧证据一致时较高,检查冲突或证据不完整时较低。为降低成本,VulnSight缓存重建的语义模式与中间候选块,以支持跨多个目标版本的重复检查。
VulnSight提供三项核心分析功能及若干支持可复用、可扩展漏洞验证工作流的实用能力。其一为漏洞产物摄取与语义重建:对漏洞v,VulnSight接受文本漏洞描述、漏洞相关修复补丁、脆弱参考快照、修复参考快照与目标项目,补丁用于定位漏洞相关变更并提供可观察证据,语义重建联合以描述、补丁及脆弱与修复参考快照为条件;据此重建两种语义抽象,其中关键脆弱与修复代码区域从补丁及相应参考快照定位,Φ项表示推断的因果语义及关联控制流与数据流约束,前者表示脆弱行为显现所需满足的漏洞触发谓词,后者表示修复引入的阻止或抑制该行为的安全或缓解谓词。该形式不假设补丁仅修改一个文件,多文件补丁保留为文件级块集合,关键区域可包含多个代码区域;当一个补丁处理多个CVE时,语义重建按每个CVE分别以其对应漏洞描述为条件进行,使所得模式特定于所分析漏洞。当前实现每次运行分析一个选定补丁,因而要求至少一个可识别的漏洞相关补丁;无可用补丁的CVE被排除在基准之外并处于支持范围之外;对于修复序列,数据集构建过程选择修改关键脆弱位置的补丁,该选择可能遗漏分布在多个提交中的纠正语义,属当前实现局限。其二为目标侧候选空间构建:给定目标项目,VulnSight提取目标侧代码块集合并构建缩减候选空间,包含与重建语义最相关的代码区域;该功能结合补丁感知定位信号、代码块分割、结构相似性过滤、同名回退检索、LLM辅助候选补充以及通过语言感知调用图分析的上下文扩展,目的是在重构、文件移动与长期代码演化下保留语义有意义证据的同时减少传入最终推理阶段的目标代码量。其三为多步语义漏洞判定:VulnSight联合评估重建模式与目标候选,而非将漏洞与修复匹配视为独立布尔状态;判定输出二值结论、未校准置信度指标与推理轨迹,置信度不决定也不阈值化二值结论,仅作为证据一致性的辅助指标报告;当现实路径展现本质漏洞语义且无有效缓解时目标被判为脆弱;部分或冲突的漏洞与修复证据被联合考虑,但当前实现仍产生二值结论,其置信度指标未校准,形式化弃权仍属未来工作。实用软件能力方面:当前实现为Python、Java与C/C++提供模块化结构分析,并在语言特定调用图后端不可用时提供文件级回退处理,当前C/C++支持为初步性;支持重建语义模式与中间参考块的持久缓存,降低同一漏洞对多个目标版本检查时的计算成本;软件既可通过命令行界面进行可复现的端到端执行,也可通过Python API将验证流水线作为可复用组件暴露给更大分析系统。
研究人员以Cleo端到端案例说明VulnSight:一次运行需要描述、补丁、脆弱与修复快照及目标版本,命令重建两种模式、提取目标候选、缓存证据并执行最终LLM引导决策。示例输出中,VulnSight将cleo-0.7.2分类为非脆弱,辅助置信度为0.95,并返回解释性轨迹;缓存记录ReDoS成因、指向_render_cell的路径、构造的TableCell数据流、修复将键限制为fg、bg与options以及相关源块;缓存的VulnPattern捕获脆弱控制流与数据流,SafePattern捕获修复引入的受限属性键逻辑。轨迹显示目标缺少实例化脆弱行为所需的表格渲染功能,否定判定源于目标早于脆弱功能而非因其包含修复。该案例表明VulnSight区分漏洞语义缺失与已实现修复语义,这一区分在早期发布落在粗糙数据库范围内但并未包含脆弱组件时尤为重要,可避免基于版本范围或表面补丁相似性的过度近似。
影响方面,评估范围上,研究人员在Python基准上评估VulnSight,并分别报告Java比较与初步C/C++案例研究。Python基准构建通过漏洞收集、补丁识别、仓库对齐与代码演化过滤完成:首先从PyPA Advisory Database与deps.dev聚合3179条漏洞记录,并用NVD、项目公告、发布说明与官方文档补充,经标识符协调、去重与元数据校正后语料含3464个不同漏洞;接着从公告引用、仓库历史、问题跟踪器与发布记录收集候选修复提交,排除仅修改文档、测试或配置文件的提交,当修复跨多个提交时选择修改关键脆弱位置的提交作为参考补丁并将其余提交保留为数据集构建中的支持证据,该过程得到687个具有可识别修复补丁与可恢复版本历史的漏洞;随后过滤历史发布以保留非平凡代码演化案例,利用deps.dev记录的受影响组件与仓库信息检索并对齐每个漏洞可用的GitHub发布,使用局部敏感哈希(LSH)将参考修复补丁修改的文件与各候选目标版本中对应文件比较,平均Jaccard相似度超过0.9的目标版本因与参考补丁高度相似而被排除,最终基准包含114个仓库中184个不同CVE与4032个漏洞—版本对。基准组成上,包含1640个标记为脆弱的对与2392个标记为非脆弱的对,每个CVE贡献1至30个版本,中位数为24,无仓库贡献超过四个CVE。参考标签上,每个漏洞—版本对被标记为脆弱或非脆弱,每个模型输出在评分前匹配到相应CVE、仓库与版本,标注完全一致率为90.82%,Fleiss κ为0.870。LLM配置与可复现性上,所有基于LLM的实验通过提供商官方API于2026年9月访问,评估后端为通过DeepSeek API的DeepSeek-R1-0528、通过Google Gemini API的gemini-2.5-pro与通过OpenAI API的o3-2025-04-16;为保证稳定可复现的漏洞验证,所有报告实验采样温度设为0.1,采用低温解码以减少不必要的输出变异同时保持有限生成灵活性;top-p与最大输出token参数未显式指定,因而遵循调用时相应API提供商的默认值;三种后端使用相同提示模板与评估输入。模型输出与评分上,每个模型在完整配置与四种消融下保存输出,全部15种配置对所有标注对提供可解析预测;评分脚本提取显式YES/NO决策,YES映射为脆弱、NO映射为非脆弱,当响应包含冲突显式决策时采用最后一个显式决策,该规则适用于DeepSeek-R1-0528–VP的143条响应以及DeepSeek-R1-0528、gemini-2.5-pro与o3-2025-04-16–SP配置中分别为77、127与104条响应,完整配置不含冲突显式决策,置信度值不决定也不阈值化二值结论。为考虑每个CVE版本数不等,以CVE宏平均准确率报告,其定义为对C=184,每个CVE等权贡献,无论其版本数多少;作为比较,对级准确率汇总所有标注对上的正确预测。Python结果与消融上,完整配置的CVE宏平均准确率为DeepSeek-R1-0528的92.99%、gemini-2.5-pro的91.70%与o3-2025-04-16的92.22%,相应配对级准确率为92.98%(3749/4032)、91.74%(3699/4032)与92.19%(3717/4032),二者为不同聚合度量;为评估运行间变异,相同设置下重复评估三次,4032个漏洞—版本对中95.11%在三次运行中获得相同判定(Fleiss κ=0.933),准确率范围92.13%至92.99%,均值92.44%,标准差0.48个百分点,显示运行间变异有限;移除VulnPattern使CVE宏平均准确率下降12.98至19.21个百分点,移除SafePattern使其下降8.66至9.27个百分点,三种后端上移除VulnPattern均导致更大降幅;禁用预处理使准确率降至43.92%至49.43%,移除多步推理使其降至43.65%至49.44%,这些结果支持两种语义模式、预处理与分阶段推理在该基准上的贡献。评估范围与泛化性上,同一CVE的版本作为观察仍聚簇,不同CVE可共享仓库,版本对不应解释为独立漏洞案例;CVE宏平均防止版本多的CVE主导报告准确率,但不建立统计独立性或生态级泛化性,结果描述在所供Python基准上的性能,更广泛化需在这些CVE与仓库之外进一步评估。Java基准比较上,研究人员在Java VISION基准上评估VulnSight,以在相同评估协议下与现有漏洞验证方法比较;移除不再可用的源归档后,基准含6305个组件发布中74个CVE的8535个漏洞—版本对,两种方法在相同标注对上评估,报告与Python评估一致的CVE宏平均准确率,每个指标先对每个CVE单独计算再在74个CVE上等权平均,零分母指标赋值为零,F1在每个CVE内计算后平均;VulnSight取得96.44%的CVE宏平均准确率,相比VISION的91.01%提高5.43个百分点,VulnSight在脆弱与非脆弱样本上亦取得更高的CVE宏平均精确率、召回率与F1。失败分析上,为分析模型局限,研究人员分别检查Python与Java评估中的假阳性(FP)与假阴性(FN);Python上DeepSeek-R1-0528、gemini-2.5-pro与o3-2025-04-16分别产生283、333与315个错误,FP/FN分布分别为165/118、197/136与209/106;Java上VulnSight在8535个漏洞—版本对上产生427个错误,包括250个FP与177个FN;所有评估中假阳性一致超过假阴性,FP/FN比范围为1.40至1.97,表明错误受影响预测构成所评估系统中的主导错误类型;按漏洞案例、版本演化特征与产物上下文进一步检查误分类样本,代表性案例人工检查揭示三种常见失败模式:一是代码演化可能迁移或修改漏洞相关逻辑,使跨版本直接证据匹配困难;二是涉及多产物(如配置、依赖或初始化文件)的漏洞在仅有部分证据时可能缺少足够上下文;三是语义相似的脆弱与修补实现可能在模型未能区分其行为差异时导致错误匹配。初步C/C++验证上,研究人员分析Apache NimBLE中的CVE-2026-45813,以1.9.0与1.10.0版本分别作为脆弱与修复参考,目标提交4ebbbf2被判为脆弱;作为重建根因语义的一部分,VulnSight识别出外部控制的num_subgroups值可在子组处理中使用而未先对照固定数组容量BLE_SVC_AUDIO_BASS_SUB_NUM_MAX检查,生成的描述将该缺失校验与潜在越界内存访问及修复补丁引入的相应边界检查联系起来;复现包包含脆弱与修复参考输入、选定补丁、提交4ebbbf2的目标快照、执行示例与生成结果;该实验仅作为初步的基于案例的验证,基于deps.dev的收集未产生合适的语言标注C/C++基准,异构构建环境阻碍了构建与Python基准直接可比的C/C++数据集。实际影响上,VulnSight执行逐版本漏洞验证,因而可支持超越启发式版本范围推断的受影响版本标注重评估;其证据块、置信度估计与结构化推理轨迹使个体决策更可检查与可审计,该能力有助于识别漏洞元数据中的不一致并为软件组成分析工具提供更精确信号;例如CVE-2012-3540被NVD标记为影响所有版本尽管已于2012年修补,而PyPA Advisory Database将全部91个可用版本包括近期发布列为受影响,此类案例说明基于证据的版本验证可支持对过宽受影响版本范围的审计与纠正。
讨论与结论方面,VulnSight通过将判定依据从脆弱的语法签名转向显式的双边语义,使漏洞存在性验证可复现;给定常规可用产物,VulnSight重建VulnPattern与SafePattern,从目标版本提取紧凑候选空间,并执行LLM引导的语义对齐以产生证据支持的判定。实证评估覆盖Python与Java漏洞—版本集合,初步Apache NimBLE案例展示代码演化下端到端C/C++处理;VulnSight为Python、Java与C/C++提供模块化预处理及语言特定调用图后端,但其C/C++支持尚未在系统基准上验证。研究人员期望VulnSight有助于研究漏洞元数据质量并验证依赖告警与受影响版本标注。当前实现要求单个可识别的漏洞相关修复补丁作为输入,尽管补丁可跨多个文件,纠正逻辑分布在多个提交中的漏洞不在当前评估覆盖范围内;将语义重建扩展为联合建模多提交修复序列仍属未来工作。