文章总结: 本文介绍Cloudflare构建模型无关的AI漏洞发现流水线的实践。为解决单模型上下文耗尽与视角局限,系统被拆分为发现与验证两阶段,并在不同阶段使用不同模型进行对抗式复核。发现流水线包含动态威胁建模、沙箱主动执行及跨仓库追踪。核心建议包括:将状态外置至数据库以保证容错;要求漏洞必须附带未修改代码的PoC与补丁;勿过早接入静态分析,应关注Agent实际使用的工具。 综合评分: 93 文章分类: AI安全,代码审计,安全建设,实战经验,漏洞分析
Cloudflare 如何搭建 AI 漏洞发现流水线
Cloudflare Blog Cloudflare Blog
不吃猹的瓜
2026年6月22日 20:56 北京
在小说阅读器读本章
去阅读
几周前,我们发布了 Project Glasswing 的初步发现,观察当你把 frontier security models 指向企业代码库时会发生什么。我们也探讨了我们的防御结构如何适应变化,以保护基础设施和客户免受 frontier AI 带来的威胁。从那以后,AI 生态仍在快速变化。那些围绕单一模型紧密构建系统的开发者,已经体验过当这个模型不再可用,或被更强模型取代时会发生什么。这些市场变化只会进一步强化我们的核心判断:无论某一天领先的是哪个底层模型,agentic workflows 的未来都不在独立模型、prompt 或单 agent session 里。
要从一个局部的安全 “skill” 走向持续的、fleet-wide 扫描 pipeline,需要一种把模型当作可替换组件的架构。依赖单一模型天然会限制防御覆盖面,因为同一个系统会倾向于用完全相同的视角看代码路径。为了抵消这一点,模型应该被频繁替换并交叉测试。通过在 pipeline 中使用不同模型,例如用一个模型做初始发现,再用完全不同的模型做验证,我们可以确保漏洞由不同的逻辑集合交叉检查。此外,真正的企业级 harness 不能只看孤立仓库,还必须沿着跨仓库依赖追踪漏洞,最终把成千上万的原始候选过滤成可信、已 triage、可执行修复的队列。
这篇文章会从实践角度介绍如何构建这种 model-agnostic 层,重点讲我们如何管理状态控制、消除误报,并在规模化场景下协调端到端 triage。
先回应两个质疑
上一篇文章解释了为什么通用 coding agents 无法胜任这项工作。主要问题在于,agent 一次只能持有一个假设,在覆盖真实 repo 的一小部分后上下文窗口就会塞满,然后又会在 context compaction 过程中丢失信息。更多细节可以阅读那篇文章。
在继续之前,我们想先回答两个可能出现的问题。
“为什么不用 subagents,而要用 harness?” Subagents 很有用,也是一个不错的起点。但安全分析需要数百个独立 investigation,它们要能跨 run 存活,不能共享同一个上下文窗口,还要能在之后重新界定范围并互相引用。它需要 persistence、deduplication、resumability,最终还需要 fleet-wide dependency tracing。这是一个 orchestration 问题,单靠 prompt 到不了那里。
“这篇博客只是 frontier models 的广告吗?” 不是。我们的方法以 harness 为中心,而不是以模型为中心。在漏洞发现上,我们会使用当前最适合需求的 frontier model。把不同模型指向同一个目标时,它们各自会找出不同部分的 bug。真正持久的是 harness 这一层。如果你要构建自己的系统,就从第一天起把它设计成 model-agnostic。这样你才能不受限制地自由选择任何模型。
一切都从一个 skill 开始
我们一开始写了一个约 450 行的 security-audit skill,在单个 repository 上运行,并不断调整 prompts,直到它能暴露真实 bug。后来,我们加入了 orchestration,让它成为整个系统的 plumbing。真正的价值在 prompts 本身,而我们的 prompts 至今仍几乎原封不动地保留着初始 skill 中的攻击者场景、bug 类别和 anti-pattern 检测。
这个 skill 被设计成在一个 session 中运行 7 阶段 audit:
- 三个并行 research agents 做 recon,并写出
architecture.md。 - 每个攻击类别运行一个 Hunter agent,尝试破坏代码,而不是审查代码。
- 对抗式 validators 尝试推翻每个 finding。
- 存活下来的 finding 会被写成面向人的 vulnerability report。
- 它们也会按 schema 输出为
findings.json,然后由机械检查验证该文件。 - 最后,一个全新的 agent 会独立地针对源码重新验证每个 finding。
- 存活并重新验证过的 findings 会提交到 ingest API。
第一个 skill 几乎可以直接映射到后来的 harness:
| Skill phase | Harness stage |
| — | — |
| Recon agents write architecture.md | Recon |
| Hunters run per attack class | Hunt |
| Validators disprove findings | Validate |
| Surviving findings become a report | Report |
| findings.json is checked mechanically for schema adherence, not correctness | Mechanical validation of line numbers and functions in findings |
| Fresh agent re-verifies findings | Independent validation |
这个 skill 能工作,但很快暴露出自己的限制。从覆盖指标看,单次运行只能找到多次运行中大约一半的 bug。根据我们的经验,它找到的 bug 也更偏向简单、不太隐蔽的那类。一旦你的流程基本变成“跑十次,然后手工 diff”,你大概就该开始考虑真正的 harness 了。
在运行和微调 skill 的过程中,我们撞上了三堵墙:
- Context exhaustion:一个小时后,上下文窗口被填满,模型会吞噬自己的记忆,立刻忘掉它花了一上午追踪的 bug。我们通过完全外部化状态打破这个瓶颈,把 LLM 当成无状态计算引擎。
- Persistence:中途崩溃意味着从头再来。因为一次 AI rate-limit error 或连接抖动而丢掉数小时工作,是一种极其昂贵的架构教训。
- Cross-repo reasoning:单仓库 session 完全看不到消费它的应用之间的关系。而当你检查组件之间的接口时,浮现出来的 bug 数量可能比想象中更多。
建议: 一个真实但最小的 harness,只需要把 Recon、Hunt 和 Validate 阶段保存在数据库中,并配一个不能提交自己 findings 的独立 Validator。在你还没有多个重要 repository 之前,完全跳过 cross-repo tracing。在你真正被噪声淹没之前,不要上专门的 Deduplication agent。先在开发环境里从一个 skill 开始,把 prompts 调好;只有当缺少下一个架构阶段成为明确瓶颈时,再去构建它。
把 skill 编码成 pipeline
这个领域里大多数 AI security write-ups 讲的是单个 repo 或一个 curated benchmark;用这种方式跑完整 fleet,并且做 cross-repo tracing,据我们所见还没有太多公开写法。我们的代码库横跨大量语言,包括 Rust、Go、C、Lua、TypeScript 和 Python,还有各种配置管理系统、静态配置和许多额外上下文。因此,我们必须提出一套适合自己的新方法。从第一次 slash-command run,到能覆盖 128 个不同 repos、自动查找并追问相关依赖的 fleet scanner,大约花了六周。编码化过程大多是机械性的:我们把 skill 的每个 phase 提升成独立 agent,在后面放一个数据库,在前面放一个 orchestrator。映射关系几乎一一对应。
整个 fleet 运行在一个统一 harness 上,不做按语言调优,并追踪 repos 之间的依赖。把语法处理交给模型,使系统具备语言无关性;但真正的差异点在于它能追踪 repo 之间的依赖。Harness 本身不关心自己看的是 C 指针还是 TypeScript 文件;它关注的是安全 orchestration 的高层逻辑。这让我们能在数百个不同代码库上扩展,而无需编写自定义语言解析。
一个两阶段漏洞研究 workflow
我们的整个漏洞研究 workflow 建立在一个两阶段 operational framework 上:Vulnerability Discovery Harness (VDH) 和 **Vulnerability Validation System (VVS)**。
VDH 作为我们的发现引擎,主动扫描代码库以暴露潜在安全问题。一旦 bug 进入 VVS(它允许多个 harness 向其中输入),它们就会经过 Deduplication、Judgment,最后进入 Fixing 阶段,后面会展开说明。
我们在 VDH 中使用一个模型,但在 VVS 中使用完全不同的模型,因此两个模型实际上是在互相复核。这有明显的安全收益:强制 Model B(VVS)判断 Model A(VDH)的输出,可以确保 finding 由一组完全不同的逻辑权重和训练数据评估;它像一个无偏、对抗式第三方,唯一职责就是无情地压力测试 Model A 的假设。从运营角度看,我们也受益于把模型供应商视作可替换商品。模型供应商可能随着时间调整 temperature、caching 和 inference effort budgets,甚至在同一个模型版本内也会变化。与其构建一个依赖模型长期表现可预测的系统,不如让 harness 能吸收下游波动而不崩。
Stage 1: Vulnerability Discovery Harness (VDH)
上一篇文章讲过每个 agent/stage 的用途,所以这里讲它没覆盖的部分:stage 之间的 glue,以及决定系统能否工作的一些细节。
| Agent/stage | Primary Role | Sub-agents / Tooling |
| — | — | — |
| Recon | 梳理目标架构并映射潜在威胁向量 | 3 个并行 Recon sub-agents 写出 architecture.md |
| Hunt | 按类别发起攻击、编译片段、探测 binaries | 它会派生 siblings(取决于模型,这些 siblings 处理 fleet-wide 任务的 9% 到 20%)。它会访问并写入 Wishlist tool。 |
| Validate | 先机械检查 finding,再以对抗方式推翻它 | 分两 pass 运行:plain code 处理初始 schema/path 检查,然后一个隔离 agent 尝试在 finding 被提交前推翻它。 |
| Gapfill | 为覆盖不足的 cell 生成新的 hunt tasks | 对任何仍显薄弱的(area × attack-class)cell 入队新的 hunt tasks |
| Dedup | 识别并合并重叠 findings | 组合 deterministic code 和 agents,按 root cause 对 findings 聚类,并实时折叠到一起 |
| Trace | 遍历 dependency graph;生成 consumer-repo tasks | 遍历 graph,在每个识别出的 consumer repo 内添加 hunt tasks,确保能捕获 cross-repo bugs |
| Feedback | 从已有 reports 中学习并优化后续 runs | 接收 validation failures、shallow runs 和反复漏报,并立即重写队列中的 prompts,让后续 tasks 更聚焦。 |
| Report | 渲染 human-readable report | 只是一个脚本,不需要模型 |
Table 1: Vulnerability Discovery Harness (VDH)
第四到第八阶段会作为连续的 producer-consumer loop 运行。随着初始 hunt 推进,Gapfill, Feedback 和 Trace agents 会生成新 tasks;Dedup 会把重叠 findings 折回到一起,loop 的其余部分则继续消费队列。这确保了即使某个漏洞在周期很晚才被发现,也仍会在同一次 run 内被验证、报告,并与其他代码比对,确认是否包含相同 bug。
这样拆分 pipeline 可以保证严格的上下文控制。如果填满上下文窗口,模型就会开始幻觉。我们让每个 agent 的工作极度聚焦,把上下文使用量控制在总窗口的 25% 以下。天真的“read all files”方法每次都会冲破这个限制。
有一件事让我们吃了亏:必须先考虑 persistence,再考虑 parallelism。你不会想因为一个意外错误就扔掉五小时的 run。每个 stage 都写入同一个 SQLite 数据库,并以(run_id, repo, stage)作为 key。任何 stage 都可以 resume、retry,或被拉进后续 run,而无需重做工作。Findings 会在产生时流式保存,所以一次 crash 只会损失正在执行的 task,其他都不会丢。
建议: 有时候 transient API error 会以文本形式出现在(200 OK)response stream 中,而不是抛出 code exception。对 orchestrator 来说,这看起来完全像是一个干净完成的 task。你必须显式分类响应文本,而不能只相信 exception type,否则最终会把空 run 记成成功。
Dynamic threat modeling
在 Recon 阶段,agent 会自己写 threat model,而不是拿到一份现成的 threat model。除了大约十个内置 attack classes(多种 injection、memory corruption、protocol parsing、timing side channels 等)之外,Recon agent 可以现场发明 repo-specific classes,每个 class 都带有自己的 methodology。它会写出一个专门为该代码库定制的 taxonomy,用来更精确地界定 Hunter agents 的范围。
只读源码不足以理解代码在压力下的行为,尤其是 C 和其他低层语言中的微妙 undefined-behavior bugs。Hunter agents 会越过代码阅读,进入主动执行。它们编译片段、构建小版本并攻击它们。质量上最大的跃升,来自给 Hunters 一个 sandbox(基于 unshare 构建)来 crash binaries。
建议: 如果 harness 本身跑在 Docker 里,这个 sandbox 需要 seccomp=unconfined 和 apparmor=unconfined,否则它会静默启动失败。这是一个一行修复,但如果你和我们一样不是 nested containerization 专家,它能帮你省下一天抓头发的时间。
Micro-forks 和 wishlist
除了核心 pipeline stages,我们还加入了两个专门机制,让 Hunters 具备更强自主性:它们可以调整关注点、请求外部资源,而不会打断正在进行的分析。
Sibling Forking:如果 Hunter agent 碰到一条有意思但超出当前范围的代码路径,这个机制能防止它跑偏。它使用 tool call 派生一个带有精确结构化 seed 的 sibling agent。从整个 fleet 看,这大约占任务的 9%,不过比例高度依赖模型:根据负责 hunting 的模型不同,从接近 0 到约五分之一不等。
The Wishlist:当 agent 需要一个自己没有的工具时,通常是 Validator 想确认 Proof of Concept (PoC),或 Hunter 想构建某些东西(比如特定 build environment、VM 或一些 prod config files),它会写入一个中心 wishlist。它提供足够上下文,让系统在人工提供依赖后能自动重新运行完全相同的 task。其中有些可以部分自愈:如果 container 需要带着某些改动重建,可以让一个 generic coding harness 监控日志,并在 run 之后自主完成。
自 wishlist 加入以来,它已经在 128 个 repos 中被写入 25,472 次,是 agents 与我们反馈沟通的主要方式。我们写这篇文章时刚收到的一条是:“*I need a FreeBSD VM to confirm this PoC end-to-end.*”
Fleet-wide cross-repo tracing
初始 cleanup 后,一个 Tracer agent 会检查不同软件组件之间如何连接。它寻找一条特定路径:潜在攻击者能否从外部向系统中易受攻击的部分发送有害输入?如果答案是 yes,Tracer agent 会自动在 consumer repository 内生成新的 hunt tasks。要做到这一点,你需要一个统一的 cross-repo symbol index 和准确的 dependency graph。这能让你发现标准单仓库扫描会错过的深层系统性缺陷。
在整个 repo fleet 上运行 harness 后,我们学到了两个只有规模化时才会浮现的经验。
第一,deduplication 本身就是一个问题,大到需要自己的 agents。当你只扫描少量 repositories 时,可以人工看出重叠 bug。简单字符串匹配或文件路径检查在这里救不了你。判断两个复杂逻辑缺陷是否真的是同一个 root bug,听起来很简单,但并不是。它需要大量认知推理,以至于我们不得不部署专门的 Dedup agents 来清理噪声,并配上它们自己的 heuristics 和降工作量方法。
第二,不要太早接入 static analysis。我们把 Semgrep 全链路接进去了,但 Hunters 在一个月的 runs 中调用了它零次。它们更愿意读代码、跑代码。相比之下,wishlist 是系统里使用最多的工具。值得关注的是 agents 实际会伸手去拿什么,而不是你以为它们想要什么。
让 findings 值得信任
Agent 会编辑源码,让自己的 exploit 能跑通,然后兴高采烈地报告它刚刚创造出来的 bug。它会写一个证明完全同义反复的测试,比如“exec() executes things, therefore critical vulnerability”。或者它构建了一个能正常运行但什么也证明不了的 exploit,因为背后的 threat model 根本不成立。如果你的 harness 不主动对抗这些情况,你构建出来的只是一个更快生产垃圾的机器。
Hunter 必须先说明 threat model,才允许提交任何东西。它必须精确定义攻击者是谁,以及该漏洞跨越了什么边界、破坏了什么假设。输出 schema 的顺序会强制执行这一点。这个要求消除了空洞 findings,比如“如果用户有数据库写权限,他们就可以写数据库”这类。
每个确认后的 finding 都会带一个 PoC,形式是针对原始、未修改代码库运行的测试。这可以防止 agent 编辑源码来强行让 exploit 成功。如果没有可工作的 PoC,我们就把 finding 当成假的。实践中,这可能是一个 Hunter 编译一个 30 行 parsing loop,开启内存保护运行它,并证明错误的 read stride 来自 stack address,而不是预期的 message body。你可以自己重新跑它。此外,每个确认后的 finding 还必须附带 proposed patch。真正进入我们 review queue 的,是一个已验证 bug、一个可运行测试和一个功能性 git diff,而不是对问题的模糊文字描述。
在 exploit path 存活下来之前,deterministic code(用 plain code 写的,而不是另一个模型)会机械验证引用的文件和路径确实存在,并确认 patch 和 test 都能正确 parse。这个 Validator 不能记录自己的 findings;它唯一的职责是积极推翻 Hunter 的理论。如果允许 Hunter 自己批改作业,它会自信地验证自己输出的一切。
我们不会宣称系统的 false-negative rate。代码库里没有一组标注好的“所有真实 bug”,所以任何 recall 数字都完全是推测。我们能观察的是 re-runs 是否仍在不断发现新 bug(确实如此),以及 coverage 是否仍在跨 run 增长。这都是 proxy,因为你无法确定单个代码库里到底有多少 bug,但这已经是一个足够好的有效性度量方式。
Stage 2: Vulnerability Validation System (VVS)
Harness 输出的 finding 只是 triage 流程的开始。所有发现都会进入一个统一共享的 VVS,目前它一共包含跨 145 个 repos 的 13,841 个 findings。Triage 这种规模本身就是一个巨大的工程问题,而且重要性不亚于 hunting。这个 triage engine 使用与 harness 不同的模型,并拆成三个独立任务。
| Agent/stage | Primary role | Spawns/ sub-agents/tooling | | — | — | — | | Dedup | 判断漏洞是否已经在系统中,或是否已经作为内部 Jira ticket 提出 | Deterministic: plain code 基于 files、functions、trust boundaries 和 rare tokens 构建 inverted indexes,然后给每个 finding 一个短 candidate list Probabilistic:Dedup agent 对这个短列表进行推理,Stable cross-run key 会重新打开已有 records | | Judgment | 生产环境可达性和验证 | 单 agent:从 MCP servers 构建 bug 上下文,以理解服务在生产中的形态。搜索 wiki、Jira、git、config 和所有其他可用来源,试图判断一个 bug 是否真正适用于我们的生产环境,并基于此对漏洞评分。它还会对照源码验证 bug 是否仍存在于最新 main branch。 | | Fixing | 生成 patches,运行 regression tests | 在修改前后都运行 regression test(过滤到受影响测试;只有无法按测试过滤时才跑完整 suite)。它要求目标测试出现干净的 fail→pass 翻转才能通过 gate。如果 patch 后测试失败,或全局运行检测到下游 regression,commit 会被自动阻止并标记给人工介入。 |
Table 2: Vulnerability Validation System (VVS)
Deduping
用 LLM 把每个 finding 和其他所有 finding 两两比较,复杂度是 O(N^2),在规模化时会完全崩掉。为了让模型离开 critical path,deterministic code 会基于结构化数据(touched files/functions、trust boundary、rare tokens)构建 inverted indexes,生成一个真正候选的短列表。只有到这个阶段,agent 才会查看这个短列表,判断一个修复是否能关闭其中多个 finding。稳定的 cross-run keys 确保重新发现的 bug 会重开已有 records,而不是生成新记录。
Contextual judgment
Judgment 是对存活 finding 的第二次独立 pass。Agent 会重新检查最新信息,从 deployment、environment 和 config context 中拉取数据,判断 code path 在 prod 中是否可达,并识别 repo owner。这个过程会把“现在可利用”从“真实但潜伏”和“真实但提交到错误组件”中区分出来。它的作用是把一堆混乱 findings 移入一个风险驱动的 orchestration workflow。
Automated fixing
Fixer 接收 proposed patch 和 unit tests,把它们改写成符合 repo 风格的形式,应用 diff,并运行 targeted tests。干净的 fail→pass 翻转是理想状态,也是唯一允许自动清理的情况;patch 后测试失败会阻止 commit。Fixer 永远不会自行合并代码;branch 必须由人审查。这个 gate 是不可协商的 human-in-the-loop safeguard,它为 change management compliance 提供了干净、不可破坏的 cryptographic trail。如果允许模型自由 patch,它会很开心地修掉一个安全 bug,同时悄悄破坏无关功能或引入几十个新 bug。
在所有三个 triage 任务中,每个 agent 都被限制在一个狭窄任务内,外面包着 deterministic bookkeeping code;没有人工批准 dry run,任何东西都不会写入生产。虽然这个 pipeline 把工程瓶颈从找 bug 转移到了 review 和落地修复上,但 Fixer 仍然是系统中最年轻、最慢的部分。
成本是多少
在整个 repo fleet 上运行数百个 agents 并不便宜,但至少支出形态是可预测的。几乎所有计算预算都直接流向 hunt stage。这让 Gapfill 成为我们的 cost-to-coverage 杠杆,因为每个额外 pass 的成本大约只有初始 hunt 的一半。
由于每个 repository 的成本差异很大,我们按 repo 而不是按 run 做预算。我们对每个 repository 强制设置严格 task cap,并启动 50 到 200 个 worker 不等的 worker pool。这样,你可以把钱花在真正找到问题的 repos 上,而不是浪费在没有产出的 repos 上。
这也是为什么对我们来说,大扫描是周期性的 backlog sweep,而不是每个 PR 都跑的检查。对复杂 repo 做一次完整扫描可能要花数小时;最糟的一次 run 刚刚超过 14 小时。更便宜、更小的 harness 才适合 per-PR 场景。
我们如何判断它有效
我们通过跟踪自动化 pipeline 如何高效地把刻意设计的工程噪声过滤成高质量、可执行 findings,来衡量系统有效性。因为我们有意调整 Hunters,让它们过度报告那些可以串成更大攻击的微妙 primitives,所以真正的成功指标,是我们能在它们到达人类面前之前,多么锐利地压缩那座原始数据山。
为此,我们精确跟踪有多少 raw findings 会随着时间存活过每个 validation stage。得益于 Recon phase 更好的 context injection,我们初始 validation rejection rate 从 40% 降到 11%,而 high-integrity findings 的占比从 35% 升到 58%(对应约 12,057 个 lifetime findings)。
下面是在这篇博客写作时,从 raw candidates 到 actionable findings 的 lifetime breakdown。
BLOG-3344 2
BLOG-3344 2
Vulnerability Discovery Harness (VDH)
- Raw candidates: Discovery harness 在 independent validation 之前输出的一切。
- Needs repro: 看起来可信,但需要人工复现后才能信任的 findings。
- Rejected at validation: Validator 推翻了 threat model、exploit path、affected code 或 evidence。
- Duplicates: 被折叠到同一 harness 中另一个 finding 上的 candidates。
- Survived validation: 通过 independent validation gate 并进入 VVS 的 findings。
- Bugs that went elsewhere: 被有意路由到这个流程之外的 findings。
Vulnerability Validation System (VVS)
- Another vulnerability harness: 向同一个 validation system 输入的其他自动化来源。
- Total bugs in system: ingest 后的合并池。
- Duplicates: Dedup pass 识别为已被另一个 canonical finding 或 ticket 覆盖的 findings。
- Wrong repo / other / not a risk: 噪声桶:归属错误的 findings、defense-in-depth,或 latent risks。
- Bugs sent to teams: 最终确定、干净、可交给团队修复的 findings。
- Judged Internet-exploitable: 现实攻击者可在生产中触发的高紧急度 findings。
- Not judged Internet-exploitable: 紧急度较低但可执行的 bugs(生产问题、依赖风险或配置错误)。
- Final severity split: 用于给工程团队分配优先级的分类。
Harness 的核心指标不是投机性的 recall score,而是尽可能让真实人类面前的 unconfirmed findings 数量接近零。架构必须是一个 relentless filtering funnel。
- 在 VDH 生成的 20,799 个 raw candidates 中,只有约 12,057 个存活过 validation。
- 当这些 findings 被推入 VVS,并与另一个 harness 的 findings 汇合后,中心池达到 13,841。
- Dedup agent 折叠掉 5,442 个 duplicates。
- 1,154 个被路由到 ‘wrong-repo’ 或 ‘low-risk’ 队列,并在适当情况下回收到系统中。
- 最终留下 7,245 个 actionable findings,供工程团队处理。
传统 compliance 规则完全基于静态 CVSS score 规定任意 remediation windows(例如“30 天内修复所有 High”)。我们的 contextual judgment layer 把这个 compliance checkbox 变成了真正的风险管理。
这个架构能够把 findings 追溯到源头,这意味着修复一个 root cause 可以解决一整簇 findings,而不是只修补单个问题。VDH 系统性能也会通过把 repos 划分成(area x attack-class)cells 来度量,并迭代运行 Gapfill agent,直到它不再产生 findings。每当我们更新底层 prompt,就会在一个 held-out repository 上测试,看看总 coverage cell 数是否真的移动。
Harness 会接入自动化 health signals,在 pipeline 早期捕获系统故障。如果一个 hunt 完成得异常快,并且没有生成 sub-hunts 或 gap tasks,通常说明有依赖崩了,而不是代码库干净。为了解决这个问题,系统会把任何零 findings 结束的 Hunter agent 标记为 “shallow”,并立即重新入队运行。
最后,系统的稳健性由前文所述的独立 triage pass 进一步强化。通过用不同模型和独立逻辑权重重新判断所有 submissions,我们确保了一种无偏、对抗式验证;它与用于发现的具体模型解耦,因此无论使用哪个模型,都能提供持续存在的信任层。
这些都还没有完成。我们一直在修改系统,它离完美科学还很远。但 raw candidate findings 现在已经很便宜,唯一值得做的工作,是把它们转化成可靠、可验证的代码修复。
构建你自己的 harness,意味着接受 AI 模型会波动,但你的 orchestration layer 不必跟着波动。通过把安全逻辑从任何单一 provider 中解耦,强制对抗式验证,并自动化 triage pipeline,你可以把一座 LLM 噪声山转化成可靠的 fleet-wide defense engine。
我们的 “North Star” 指标:衡量真实世界速度
每个代码库都有些不同。为了展示这套系统在真实世界中如何工作,我们基于一次标准 repo run 绘制了一个现实 benchmark。请记住,这代表的是单个 repo 上的一次 pass;随着时间推移,持续的 fleet-wide loop 会对 findings 去重、过滤和回收,将 lifetime candidates 规模减少约 65%。
通过自动 patching 节省工程时间: 我们不关注静态 baseline,而是通过技术吞吐量、处理速度,以及消除人工 triage 瓶颈的能力来衡量 pipeline 健康度:
- Initial Validation Cut: 对于一个标准 repository(约 30k 行代码),这会产生 100 个初始 findings,完整 run 需要 3-4 小时,并在整个过程中保持高度聚焦的上下文窗口。
- Compression: Deduplication 和 Contextual Judgment Layers 并行处理这些 candidates。3 小时内,系统会把这批 findings 从约 100 个 raw candidates 压缩并精炼成 80 个 distinct, high-fidelity bugs。
- Remediation: 自动化 Fixer 以平均每个 bug 5 分钟的速度处理这 80 个 distinct bugs。总体上,系统可以在约 14 小时内发现、验证、去重,并打开功能性 pull requests。
缩短关键缺陷的 mean-time-to-resolve: 当然,你不能一次性把 80 个 patches 倒进生产,否则会把东西弄坏。为了保证部署安全,我们的系统使用分层 rollout:
- Critical Exposure Containment:系统隔离 critical、high 和 exploitable bugs(平均 80 个中约 10 个)。我们会快速推进这些进入人工 review 和 release cycles,使它们在 5 天内完整 patch 到生产环境。
- Incremental Hardening: 剩下的 latent risks、minor config anomalies 和较低紧急度 bugs,会在 15-20 天窗口内逐步滚入 prod,以保证平台稳定性。
我们如何处理所有这些 patching
这些 findings 来自一个隔离、ring-fenced 的研究实验,目的是压力测试我们的代码。它们不代表 live production environment 中仍处于 active、unpatched 状态的漏洞。
因为 harness 在我们的测试环境中持续运行,到你读到这篇文章时,这些具体数字已经完全过时了。Pipeline 暴露出的每一个 bug,都附带一个用于演示 bug 的 working test case 和一个 draft patch。我们的安全团队正在系统性处理这些 reports,并应用必要修复,这意味着你每天使用的 Cloudflare 产品已经在主动针对这些 vectors 加固。
随这篇博客一起发布的,是我们用来开发 harness 的初始 skill。发布前它被稍微清理过,以便更容易理解和集成,但 skill 本身基本保持不变。希望 harness 自身也会很快发布。它可以作为你自己的 vulnerability harness、你自己的 skill,或任何最适合你需求的东西的起点:github.com/cloudflare/security-audit-skill
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:不吃猹的瓜 Cloudflare Blog Cloudflare Blog《Cloudflare 如何搭建 AI 漏洞发现流水线》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。







评论