构建你自己的漏洞检测框架
本文深入探讨了多阶段漏洞发现框架和自动化分类循环背后的技术架构。了解如何管理状态控制、通过对抗性审查消除误报,以及规避LLM上下文限制。
几周前,我们发布了Project Glasswing的初步发现,探讨了将前沿安全模型应用于企业代码库时会发生什么。我们还研究了防御结构如何适应以保护基础设施和客户免受前沿AI的威胁。此后,AI生态系统继续快速变化——围绕单一模型构建的开发者已经体验到当该模型不再可用或被更强大的模型取代时的后果。这些市场变化强化了我们的核心论点:无论当前哪个底层模型领先,代理工作流的未来都不会存在于独立模型、提示或单代理会话中。
从本地化的安全“技能”转变为持续的全舰队扫描管道需要一种架构,其中模型被视为可互换的组件。依赖单一模型本质上限定了防御范围,因为同一系统倾向于通过完全相同的视角查看代码路径。为了应对这一点,应该频繁交换和交叉测试模型。通过在管道中变化模型——例如使用一个模型进行初始发现,使用完全不同的模型进行验证——我们可以确保漏洞被不同的逻辑集交叉检查。此外,真正的企业级框架必须超越孤立的仓库,跨仓库依赖关系追踪漏洞,最终将数千个原始候选过滤为可信的、经过分类的可操作修复队列。
本文作为构建该模型无关层的实用指南,重点介绍我们如何管理状态控制、消除误报以及协调端到端的分类。
首先,我们要解决两个可能的反对意见。第一个是:“为什么不使用子代理而不是框架?”子代理很有用,是一个好的起点。但安全分析需要数百个独立的调查,这些调查需要在运行之间持续存在,不共享上下文窗口,并且可以稍后重新调整范围和交叉引用。它需要持久性、去重、可恢复性,以及最终的全舰队依赖追踪。这是一个编排问题,提示无法解决。第二个是:“这篇博文只是前沿模型的广告吗?”不。我们的方法以框架为中心,而不是模型。在漏洞发现方面,我们使用当前最适合我们需求的前沿模型。当我们将不同模型指向同一目标时,它们各自发现不同比例的漏洞。框架是持久的。如果你构建自己的系统,请从一开始就设计成模型无关的。
一切都始于一个技能。我们从约450行的安全审计技能开始,在单个仓库上运行,并调整提示直到发现真实漏洞。后来,我们添加了编排,成为整个系统的管道。真正价值在于提示本身,我们的提示几乎未改变地保留了初始技能的威胁场景、漏洞类别和反模式检测。该技能在一个会话中执行7阶段审计:三个并行研究代理进行侦察并写入architecture.md;一个猎人代理按攻击类别运行,试图破坏代码而不是审查;对抗性验证器试图反驳每个发现;幸存者被编写为人类可读的漏洞报告;它们也按模式输出为findings.json,并通过机械检查验证文件;最后,一个全新的代理独立重新验证每个发现。
该技能直接映射到后来的框架。但它迅速暴露了局限性:单次运行只发现约一半的漏洞,且偏向于较简单和较不微妙的漏洞。我们遇到了三大墙壁:上下文耗尽、持久性和跨仓库推理。我们通过完全外部化状态、将LLM视为无状态计算引擎来打破上下文瓶颈。持久性通过每个阶段写入SQLite数据库来解决,任何阶段都可以恢复、重试或纳入后续运行。跨仓库推理通过追踪依赖关系图,确保在消费者仓库中捕获跨仓库漏洞。
将该技能编纂为管道:从第一次斜杠命令运行到覆盖128个独立仓库的舰队扫描器花费了大约六周。编纂主要是机械性的:我们将每个阶段提升为自己的代理,后面放一个数据库,前面放一个编排器。映射几乎是一对一的。整个舰队在一个统一的框架上运行,无需针对语言进行调优,并追踪仓库间的依赖关系。
漏洞研究工作流基于两阶段操作框架:漏洞发现框架(VDH)和漏洞验证系统(VVS)。VDH作为发现引擎,主动扫描代码库以发现潜在安全问题。漏洞进入VVS后,经历去重、判断和修复阶段。我们在VDH中使用一个模型,在VVS中使用完全不同的模型,因此模型相互双重检查。强制模型B判断模型A的输出,确保发现由完全不同的逻辑权重和训练数据评估,作为无偏见的对抗第三方。
VDH包括侦察、狩猎、验证、补缺、去重、追踪、反馈和报告阶段。阶段四到八作为持续的生产者-消费者循环运行。随着初始狩猎的进行,补缺、反馈和追踪代理生成新任务;去重将重叠的发现折叠在一起;循环继续消耗队列。这种拆分确保了严格的状态控制:每个代理的任务超聚焦,将上下文使用保持在总窗口的25%以下。持久性需要在并行化之前考虑:每个阶段写入SQLite数据库,键为(run_id, repo, stage)。任何阶段都可以恢复、重试或纳入后续运行,而无需重做工作。发现结果实时流式保存,因此崩溃只丢失进行中的任务。