几周前,我们发布了 Project Glasswing 的初步发现,探讨了将前沿安全模型应用于企业代码库时会发生什么。我们还研究了防御结构如何适应以保护我们的基础设施和客户 免受前沿 AI 带来的威胁。自那以后,AI 生态系统持续快速变化——那些紧密围绕单一模型构建的开发者已经体验过当该模型不再可用或被更强大的模型取代时会发生什么。这些市场变化只会强化我们的核心论点:无论在任何一天哪个底层模型领先,智能体工作流的未来都不会存在于独立的模型、提示词或单智能体会话中。
从本地化的安全“技能”转向持续的、全舰队范围的扫描管道,需要一种将模型视为可互换组件的架构。依赖单一模型本质上限制了防御覆盖范围,因为同一系统往往会通过完全相同的视角审视代码路径。为了应对这一点,模型应频繁互换并进行交叉测试。通过在管道中变化模型——例如使用一个模型进行初始发现,使用完全不同的模型进行验证——我们可以确保漏洞由不同的逻辑集进行交叉检查。此外,真正的企业级框架必须超越孤立的仓库,跨仓库依赖追踪漏洞,最终将数千个原始候选过滤为一个可信的、经过分类的可操作修复队列。
本文旨在提供构建该模型无关层的实用指南,重点介绍我们如何管理状态控制、消除误报以及大规模协调端到端分类。
第一篇文章阐述了为什么通用编码智能体无法胜任这项工作。主要问题在于智能体一次只持有一个假设,在覆盖真实仓库的一小部分后填满上下文窗口,然后在上下文压缩期间丢失信息。更多详情,请阅读那篇文章。
在继续之前,我们想回答两个可能的问题。
“为什么不使用子智能体代替框架?” 子智能体很有用,并且是一个很好的起点。但安全分析需要数百个独立的调查,这些调查能在多次运行中存活,不共享上下文窗口,并且可以在以后重新定义范围和交叉引用。它需要持久性、去重、可恢复性,以及最终的全舰队依赖追踪。这是一个编排问题,提示词无法解决。
“这篇博文只是前沿模型的广告吗?” 不是。我们的方法以框架为中心,而非模型。在漏洞发现方面,我们使用当前最适合我们需求的前沿模型来运行它。当我们让不同模型针对同一目标时,每个模型都会发现不同比例的漏洞。框架才是持久的部分。如果你构建自己的系统,请从一开始就设计为模型无关。这将使你能够自由使用任何选择的模型,不受限制。
一切始于一项技能
我们从大约 450 行的 security-audit
我们在单个仓库上运行了一个技能,并调整提示词,直到发现真正的漏洞。后来,我们添加了编排,它成为了整个系统的管道。真正的价值在于提示词本身,我们的提示词几乎原封不动地保留了初始技能的攻击场景、漏洞类别和反模式检测。
该技能被设计为在一次会话中执行7阶段审计:
三个并行研究代理进行侦察并编写 architecture.md
。
每个攻击类别运行一个 Hunter 代理,尝试破坏代码而非审查代码。
对抗性验证器尝试反驳每个发现。
幸存者被整理成一份人类可读的漏洞报告。
它们也会以 findings.json 的形式输出,遵循一个模式,并通过机械检查验证该文件。
最后,一个新的代理独立地根据源代码重新验证每个发现。
幸存且经过重新验证的发现被提交到摄取API。
第一个技能几乎直接映射到后来的框架:
技能阶段
| 框架阶段 |
|---|
侦察代理编写 architecture.md |
| 每个攻击类别运行猎人 |
| 验证器反驳发现 |
| 幸存发现生成报告 |
findings.json 通过机械检查验证模式符合性,而非正确性
| 对发现中的行号和函数进行机械验证 |
新代理重新验证发现 | 独立验证 |
该技能有效,但很快暴露了其局限性。查看覆盖率指标,单次运行只能发现多次运行中约一半的漏洞。根据我们的经验,它发现的漏洞往往偏向于更简单、更不微妙的。一旦你的流程基本上是“运行十次然后手动比较差异”,你可能就需要开始考虑一个真正的框架了。
在运行和微调该技能的过程中,我们遇到了三个障碍:
上下文耗尽:一小时后,上下文窗口填满,模型会蚕食自己的记忆,瞬间忘记它花了一上午追踪的漏洞。我们通过完全外部化状态来打破这个瓶颈,将LLM视为无状态计算引擎。
建议: 一个真正但最小化的框架仅由侦察、狩猎和验证阶段组成,保存在数据库中,并有一个单独的验证器,它不能提交自己的发现。在你有多个重要仓库之前,完全跳过跨仓库追踪。跳过专门的去重代理,直到你被噪音淹没。从开发环境中的技能开始,让你的提示词工作良好,只有当缺少某个架构阶段成为具体瓶颈时,才构建下一个阶段。
将技能编码为管道
该领域大多数 AI 安全文章都只涉及单个仓库或精心策划的基准测试;像这样跨仓库追踪、运行整个代码库群的方式,我们尚未在其他地方见过。我们的代码库涵盖了大量语言——Rust、Go、C、Lua、TypeScript 和 Python,以及各种配置管理系统、静态配置和各类额外上下文。因此,我们必须提出一种适合我们的新方法。从第一次斜杠命令运行到能够覆盖 128 个不同仓库、自动查找并询问相关依赖的代码库群扫描器,大约花了六周时间。编码过程主要是机械性的:我们将技能的每个阶段提升为独立的代理,在其后放置数据库,在其前放置编排器。映射几乎是一对一的。
整个代码库群运行在统一的框架上,无需针对每种语言进行调整,并追踪仓库之间的依赖关系。虽然将语法处理卸载给模型使系统与语言无关,但其独特之处在于能够追踪仓库之间的依赖关系。该框架本身并不关心它是在查看 C 指针还是 TypeScript 文件;它专注于安全编排的高级逻辑。这使我们能够扩展到数百个不同的代码库,而无需编写自定义语言解析。
两阶段漏洞研究工作流
我们的整个漏洞研究工作流建立在两阶段操作框架之上:漏洞发现框架 (VDH) 和漏洞验证系统 (VVS)。
VDH 作为我们的发现引擎,主动扫描代码库以发现潜在安全问题。一旦漏洞进入 VVS(允许多个框架向其输入数据),它们将经历去重、判断和最终修复阶段,我们稍后会讨论这些。
我们为 VDH 使用一个模型,但为 VVS 使用完全不同的模型,因此模型实际上是相互双重检查的。这有一个明显的安全优势:通过强制模型 B (VVS) 判断模型 A (VDH) 的输出,你确保发现结果由一组完全不同的逻辑权重和训练数据评估——这组数据作为一个无偏见的、对抗性的第三方,其唯一任务是无情地压力测试模型 A 的假设。在操作上,我们受益于将模型提供商视为可互换的商品。模型提供商可能会随时间改变温度、缓存和推理预算,即使在同一模型版本内也是如此。我们的框架并非构建一个依赖于模型随时间可预测行为的系统,而是设计为吸收下游波动而不崩溃。
阶段 1:漏洞发现框架 (VDH)
第一篇文章介绍了每个代理/阶段的用途,因此我们将讨论它未涉及的部分:阶段之间的粘合剂,以及决定其是否有效的少数细节。
代理/阶段 | 主要角色
| 子代理/工具 |
|---|
侦察
| 映射目标架构并绘制潜在威胁向量 | 3 个并行的侦察子代理编写 architecture.md |
狩猎 | 执行每类攻击、编译片段、探测二进制文件 | 它会生成兄弟代理(根据模型不同,这些代理处理代码库群中 9% 到 20% 的任务)。它会访问并写入愿望清单工具。 |
验证 | 机械检查发现,然后对抗性反驳 | 分两轮运行:纯代码处理初始模式/路径检查,然后一个独立的代理在发现被提交前尝试反驳它。 |
补缺 | 为空的覆盖单元生成新的狩猎任务 | 为任何测试不足的(区域×攻击类别)单元(看起来仍然薄弱)入队新的狩猎任务 |
去重 | 识别并合并重叠的发现 | 结合确定性代码和代理,按根本原因对发现进行聚类,实时合并它们 |
追踪 | 遍历依赖图;生成消费者仓库任务 | 遍历图,在每个识别的消费者仓库中添加狩猎任务,以确保捕获跨仓库的漏洞 |
反馈 | 从现有报告中学习并优化未来运行 | 获取验证失败、浅层运行和重复遗漏,并立即重写队列中的提示,使未来的任务更精准。 |
报告 | 生成人类可读的报告 | 只是一个脚本,不需要模型 |
表1:漏洞发现工具集(VDH)
第四到第八阶段作为一个持续的生产者-消费者循环运行。随着初始狩猎的进行,补缺、反馈和追踪代理生成新任务;去重将重叠的发现合并回去,循环的其余部分继续消费队列。这确保了在周期后期发现的漏洞仍然被验证、报告并与其他代码检查,以确保它不包含相同的漏洞,所有这些都在同一运行中完成。
以这种方式拆分管道保证了严格的上下文控制。如果填满上下文窗口,模型就会开始产生幻觉。我们让每个代理的工作高度聚焦,将上下文使用量保持在总窗口的25%以下。一个简单的“读取所有文件”方法每次都会超过这个限制。
我们遇到的一个问题是,持久性需要在并行性之前考虑。你不想因为一个不可预见的错误而丢弃一个五小时的运行。每个阶段都写入一个SQLite数据库,键为(run_id
, repo
, stage
)。任何阶段都可以恢复、重试或纳入后续运行,而无需重复工作。发现结果在发生时即被流式传输并保存,因此崩溃只会丢失正在进行的任务,而不会丢失其他内容。
建议:有时,瞬态API错误会以文本形式出现在(200 OK
)响应流中,而不是抛出代码异常。对编排器来说,这看起来完全像一个正常完成的任务。你必须显式地对响应文本进行分类,而不仅仅是信任异常类型,否则你最终会将空运行记录为成功。
在侦察阶段,代理会编写威胁模型,而不是被提供一个。除了大约十个内置攻击类别(多种形式的注入、内存损坏、协议解析、时序侧信道等)之外,侦察代理可以即时发明特定于仓库的类别,每个类别都有自己的方法论。它编写一个专门针对该代码库定制的自定义分类法,用于更严格地限定猎人代理的范围。
仅阅读源代码不足以理解其在压力下的行为,尤其是对于 C 和其他底层语言中微妙的未定义行为错误。Hunter 智能体不再局限于代码阅读,而是转向主动执行。它们编译代码片段,构建小型版本,并对其进行攻击。质量的最大提升来自于为 Hunter 提供一个沙箱(基于 unshare 构建)来使二进制文件崩溃。
建议: 如果测试工具本身运行在 Docker 内,该沙箱需要 seccomp=unconfined 和 apparmor=unconfined,否则会静默启动失败。这是一个一行代码的修复,如果你不像我们一样是嵌套容器化方面的专家,它可以为你节省一天的困惑时间。
微分支与愿望清单
除了核心流水线阶段,我们还添加了两种专门机制,赋予 Hunter 显著的自主性,使其能够调整关注点并请求外部资源,而不会中断正在进行的分析:
兄弟分支:这有助于确保如果 Hunter 智能体遇到当前范围之外的有趣代码路径,它不会偏离轨道。它使用工具调用,以精确的结构种子分支出一个兄弟智能体。在整个集群中,这约占任务的 9%,但该比例高度依赖于模型——从接近零到约五分之一,具体取决于哪个模型在进行狩猎。
愿望清单:当智能体需要它没有的工具时(通常是 Validator 确认概念验证(PoC),或 Hunter 想要构建某些东西,如特定的构建环境、虚拟机或一些生产配置文件),它会写入一个中央愿望清单。它提供足够的上下文,以便系统在人类提供依赖项后自动重新执行该确切任务。其中一些可以部分自愈:如果容器需要重建并做一些更改,这可以在运行后通过让通用编码工具监控日志来自动完成。
自愿望清单添加以来,已在 128 个仓库中被写入 25,472 次,这是智能体与我们对话的主要方式。在我们撰写本文时,有一个愿望清单落地:"我需要一个 FreeBSD 虚拟机来端到端确认这个 PoC。"
集群范围的跨仓库追踪
在初始清理之后,Tracer 智能体会检查不同软件组件之间的连接方式。它寻找一条特定路径:潜在攻击者能否从外部向系统的脆弱部分发送有害输入?如果答案是肯定的,Tracer 智能体会自动在消费者仓库内生成新的狩猎任务。为此,你需要一个统一的跨仓库符号索引和准确的依赖关系图。这使你能够发现标准单仓库扫描会遗漏的深层系统性缺陷。
在整个仓库集群上运行我们的测试工具揭示了两个教训,这些教训只有在大规模运行时才会显现。
首先,去重本身就是一个问题,大到需要自己的智能体。当你扫描少量仓库时,可以手动检查重叠的错误。简单的字符串匹配或文件路径检查在这里帮不了你。确定两个复杂的逻辑缺陷是否实际上是同一个根本错误听起来很简单,但事实并非如此。它需要大量的认知推理,以至于我们不得不部署专门的 Dedup 智能体来清理噪声,并配备它们自己的启发式方法和减少工作量的方式。
第二点是不要过早引入静态分析。我们全程集成了 Semgrep,但 Hunters 在一个月的运行中调用了它零次。他们更愿意阅读和运行代码。相比之下,愿望清单是系统中使用最多的工具。值得关注的是智能体实际使用的工具,而不是你认为他们想要的。
生成可信的发现
智能体会修改源代码以使自己的漏洞利用生效,然后得意地报告它刚刚制造的漏洞。它会编写一个测试,证明完全同义反复的内容,比如“exec() 执行事物,因此存在严重漏洞”。或者它构建一个运行正常但毫无意义的漏洞利用,因为其背后的威胁模型是荒谬的。如果你的测试框架不主动对抗这一点,你只是制造了一种更快产生垃圾的方法。
Hunter 在允许提交任何发现之前,必须陈述威胁模型。它必须精确定义攻击者是谁,以及漏洞跨越了哪个边界或打破了哪个假设。输出模式的顺序强制执行了这一点。这一要求消除了空洞的发现,比如“如果用户拥有数据库写入权限,他们就可以写入数据库”这类。
每个确认的发现都附带一个 PoC,该 PoC 作为针对原始、未修改代码库运行的测试。这防止了智能体编辑源文件以强制漏洞利用成功。如果没有可用的 PoC,我们将该发现视为伪造。在实践中,这意味着 Hunter 编译一个三十行的解析循环,在启用内存保护的情况下运行,并证明错误的读取步幅源自栈地址而非预期的消息体。你可以自己重新运行它。此外,每个确认的发现还必须附带一个建议的补丁。最终进入我们审查队列的是一个经过验证的漏洞、一个可工作的测试和一个功能性的 git diff,而不仅仅是一个模糊的问题文本描述。
在漏洞利用路径存活之前,确定性代码(用普通代码编写,而非另一个模型)机械地验证引用的文件和路径确实存在,并确认补丁和测试都能正确解析。这个 Validator 不能记录自己的发现;它的唯一任务是积极反驳 Hunter 的理论。如果允许 Hunter 给自己的作业打分,它会自信地验证自己输出的所有内容。
我们不为系统声称假阴性率。没有代码库中每个真实漏洞的标记集,因此任何声称的召回率都是完全推测性的。我们能观察的是重新运行是否不断发现新漏洞(确实如此),以及覆盖率是否在多次运行中持续增长。这些都是代理指标,因为你无法确切知道单个代码库中存在多少漏洞,但这是衡量有效性的足够好的方法。
阶段 2:漏洞验证系统(VVS)
从测试框架中产生的发现只是分类过程的开始,所有发现都进入一个单一的共享 VVS,目前总共包含 145 个仓库中的 13,841 个发现。对如此数量的发现进行分类本身就是一个巨大的工程问题,其重要性不亚于漏洞狩猎。该分类引擎使用与测试框架不同的模型,分为三个不同的任务。
智能体/阶段 | 主要角色
| 生成/子智能体/工具 |
|---|
去重 | 判断漏洞是否已存在于系统中,或已作为内部 Jira 工单提出 | 确定性方法: 纯代码在文件、函数、信任边界和稀有令牌上构建倒排索引,然后为每个发现提供一份简短的候选列表 概率性方法: 去重代理对该简短列表进行推理,稳定的跨运行键重新打开已有记录 |
判断 | 生产环境可达性与验证 | 单一代理——从 MCP 服务器构建关于该漏洞的上下文,以了解该服务在生产环境中的形态。搜索 wiki、Jira、git、配置以及所有其他可用来源,尝试理解某个漏洞是否真正适用于我们的生产环境,然后据此对漏洞进行评分。它还会根据源代码验证漏洞,以判断该漏洞在最新的主分支上是否仍然存在。 |
修复 | 生成补丁,运行回归测试 | 在修复前后运行回归测试(仅针对受影响的测试;当无法按测试过滤时运行完整测试套件)。它需要在目标测试上实现干净的失败→通过翻转才能通过关卡。如果补丁后测试失败,或者全局运行检测到下游回归,则提交会被自动阻止并标记为需要人工干预。 |
表 2:漏洞验证系统(VVS)
使用 LLM 将每个发现与其他所有发现进行比较,其规模为 O(N^2),在大规模场景下完全不可行。为了让模型远离关键路径,确定性代码在结构化数据(涉及的文件/函数、信任边界、稀有令牌)上构建倒排索引,以生成一份简短的真正候选列表。只有在这之后,代理才会查看该简短列表,判断单个修复是否能解决其中多个问题。稳定的跨运行键确保重新发现的漏洞会重新打开已有记录,而不是创建新记录。
判断是对幸存下来的发现进行的第二次独立处理。代理重新检查最新信息,从部署、环境和配置上下文中获取数据,以确定代码路径在生产环境中是否可达,并识别仓库所有者。此过程将“当前可利用的”漏洞从“真实但潜伏的”漏洞以及“真实但针对错误组件提交的”漏洞中筛选出来。它将一堆混乱的发现转化为风险驱动的编排工作流。
修复器获取建议的补丁和单元测试,将其重写以匹配仓库的风格,应用差异,并运行针对性测试。干净的失败→通过翻转是理想情况,也是唯一的自动清理情形;补丁后测试失败会阻止提交。修复器从不自行合并代码;必须由人类审查分支。这一关卡是不可协商的、人在回路中的安全措施,为变更管理合规性提供了清晰、不可破解的加密追踪。如果允许自由打补丁,模型会愉快地修复安全漏洞,同时悄悄破坏不相关的功能或引入大量新漏洞。
在所有三个分类任务中,每个代理都被限制在一个狭窄的任务内,并由确定性的记账代码包裹,且没有人类对试运行签字确认,任何内容都不会写入生产环境。虽然这一流水线将工程瓶颈从发现漏洞转移到了审查和落地修复上,但修复器仍然是系统中最年轻、最慢的部分。
在大量仓库上运行数百个代理并不便宜,但至少支出模式是可预测的。几乎所有的计算预算都直接用于搜索阶段。这使得 Gapfill 成为我们成本与覆盖率的杠杆,因为每次额外扫描的成本大约只有初始搜索的一半。
由于每个仓库的成本差异很大,我们按仓库而非按运行来预算。我们对每个仓库强制执行严格的任务上限,并启动一个包含 50 到 200 个工人的工作池。这样,你可以将资金花在那些实际能发现问题的仓库上,而不是浪费在那些没有发现的仓库上。
这也是为什么对我们来说,大型扫描是周期性的积压清理,而不是每次 PR 检查。对一个复杂仓库的完整扫描可能需要数小时;最糟糕的一次运行耗时超过 14 小时。更便宜、更小型的工具更适合这项工作。
我们通过跟踪自动化管道如何高效地将有意的工程噪音过滤为高质量、可操作的发现来衡量系统的有效性。因为我们有意将 Hunter 调校为过度报告可能被链结成更大攻击的细微原语,所以我们真正的成功指标是,在数据到达人工之前,我们能将最初的大量原始数据提炼得多么精准。
为了衡量这一点,我们跟踪每个验证阶段中原始发现的数量随时间的变化。得益于侦察阶段更好的上下文注入,我们的初始验证拒绝率从 40% 下降到 11%,而高完整性发现的比例从 35% 上升到 58%(代表约 12,057 个生命周期发现)。
以下是撰写这篇博文时,从原始候选到可操作发现的整个生命周期分解。
漏洞发现工具 (VDH)
原始候选: 发现工具在独立验证之前输出的所有内容。
需要复现: 看似合理但需要手动复现才能信任的发现。
验证拒绝: 验证器否定了威胁模型、利用路径、受影响的代码或证据。
重复: 候选被合并到同一工具的其他发现中。
通过验证: 通过独立验证门并进入 VVS 的发现。
流向别处的漏洞: 有意路由到此流程之外的发现。
漏洞验证系统 (VVS)
其他漏洞工具: 输入同一验证系统的其他自动化来源。
系统中的总漏洞数: 摄入后的合并池。
重复: 去重过程识别为已被其他规范发现或工单覆盖的发现。
错误仓库/其他/非风险: 噪音桶:错误归属的发现、纵深防御或潜在风险。
发送给团队的漏洞: 最终确定的、干净的、可供修复的发现。
判定为互联网可利用: 高紧急性的发现,现实攻击者可在生产环境中触发。
未判定为互联网可利用: 较低紧急性的可操作漏洞(生产问题、依赖风险或配置错误)。
最终严重性分类: 用于为工程团队分配优先级的分类。
该工具的核心指标不是推测性的召回率——而是将未确认发现呈现在真实人类面前的数量尽可能接近于零。架构必须是一个无情的过滤漏斗。
在 VDH 生成的 20,799 个原始候选中,只有大约 12,057 个通过了验证。
当这些发现与来自另一个测试框架的发现一起被推入 VVS 后,中央池的数量达到了 13,841。
Dedup 代理折叠了 5,442 个重复发现。
1,154 个发现被路由到队列中,标记为“错误仓库”或“低风险”,并在适当时回收回系统。
最终,剩下 7,245 个可操作的发现供工程团队处理。
传统的合规规则基于静态的 CVSS 分数规定任意的修复窗口(例如,“30 天内修复所有高风险”)。我们的上下文判断层将这个合规复选框转变为实际的风险管理。
该架构能够将发现追溯到其源头,这意味着修复单个根本原因可以解决整个发现集群,而不仅仅是修补个别问题。VDH 系统性能还通过将仓库划分为(区域 x 攻击类别)单元并迭代运行 Gapfill 代理直到其停止产生发现来衡量。每当我们更新底层提示时,我们都会针对一个保留的仓库进行测试,以查看总覆盖单元数是否实际变化。
测试框架连接自动化健康信号,以便在管道早期捕获系统故障。如果一次搜索完成得异常快,并且未能生成子搜索或间隙任务,通常表明依赖项崩溃,而不是代码库干净。为了解决这个问题,系统将任何完成时发现数为零的 Hunter 代理标记为“浅层”,并立即将其重新排队以进行新的运行。
最后,我们系统的稳健性通过前面描述的独立分类过程得到加强。通过使用不同的模型和独立的逻辑权重重新判断所有提交,我们确保了一个无偏见的对抗性验证,该验证与用于发现的具体模型解耦,提供了一个无论使用哪个模型都持续存在的信任层。
这一切都尚未完成。我们不断更改我们的系统,它远非一门完美的科学。但原始候选发现现在很便宜,唯一值得做的工作是将它们转化为可靠、可验证的代码修复。
构建你自己的测试框架意味着接受 AI 模型是不稳定的,但你的编排层不必如此。通过将你的安全逻辑与任何单一提供商解耦、强制对抗性验证以及自动化你的分类管道,你可以将大量的 LLM 噪音转化为一个可靠的、覆盖整个舰队的安全引擎。
我们的“北极星”指标:衡量实际速度
每个代码库都略有不同,因此为了向你展示这在现实世界中是如何工作的,我们基于一个标准仓库的运行绘制了一个现实的基准。请记住,这代表了对一个仓库的单次通过;随着时间的推移,随着持续的全舰队循环去重、过滤和回收发现,它将生命周期候选数量减少了大约 65%。
通过自动补丁节省的工程工时: 我们不是关注静态基线,而是通过技术吞吐量、处理速度以及消除手动分类瓶颈的能力来衡量我们管道的健康状况:
初始验证削减: 对于一个标准仓库(约 3 万行代码),这会产生 100 个初始发现,完整运行需要 3-4 小时,在整个过程中保持高度聚焦的上下文窗口。
压缩: 去重层和上下文判断层并行处理这些候选结果。在3小时内,系统将一批约100个原始候选发现压缩并精炼为80个不同的、高保真的漏洞。
修复: 自动化修复器以平均每个漏洞5分钟的速度处理这80个不同的漏洞。总计,系统可以在大约14小时内完成发现、验证、去重并打开功能性的拉取请求。
缩短关键缺陷的平均修复时间: 当然,你不能一次性将80个补丁全部投入生产而不引发问题。为了确保部署安全,我们的系统采用分层推出策略:
关键暴露遏制: 系统隔离关键、高危和可利用的漏洞(平均80个中的10个)。我们优先安排人工审查,并将其引入发布周期,在5天内完成生产环境的全面修补。
渐进式加固: 其余潜在风险、次要配置异常和低优先级漏洞在15-20天内逐步引入生产环境,以保证平台稳定性。
我们如何处理所有这些补丁
这些发现是一项隔离的、封闭的研究实验的结果,旨在对我们的代码进行压力测试。它们并不代表我们生产环境中活跃的、未修补的漏洞。
由于测试工具在我们的测试环境中持续运行,当你阅读本文时,这些具体数字已经完全过时。流水线发现的每一个漏洞都附带一个可工作的测试用例来演示该漏洞,以及一个草稿补丁。我们的安全团队正在系统地处理这些报告并应用必要的修复,这意味着你每天使用的Cloudflare产品已经针对这些攻击向量进行了主动加固。
除了这篇博文,我们还发布了用于开发测试工具的初始技能,在发布前已稍作清理,使其更易于理解和集成,但技能本身基本保持不变。希望测试工具本身也能很快发布。这可以成为你自己漏洞测试工具、技能或任何最适合你需求的起点:
github.com/cloudflare/security-audit-skill
如果你的团队也在解决同样的问题,并希望交流经验,请通过 [email protected] 联系我们。
