开源项目第222期:security-audit — Cloudflare 的安全审计 Skill,把 Coding Agent 变成六阶段安全审计器

文章来源声明: 原文作者:冬奇Lab; 来源站点:掘金; 原文链接:https://juejin.cn/post/7686774243414687779; 本文基于上述来源整理/加工,觅优补充点评,仅供技术学习交流。版权归原作者所有。
觅优短评

它解决的不是「AI 能否发现漏洞」,而是「发现的结果能否被安全团队信任」。适合用 Claude Code 等 agent 做代码安全审查的团队借鉴其流程与验证边界设计。

引言 --

"A coding-agent skill for multi-phase security audits with independently verified, machine-readable findings."

这是「每日一个开源项目」系列的第 222 篇。今天的项目是 security-audit —— Cloudflare 出品的 coding-agent skill,13,825 颗 Star,MIT 许可证。

security-audit 解决一个关键问题:怎样让 AI Agent 做的安全审计,结果可信到能交给安全团队审阅? 答案不是"让模型更聪明",而是用一套结构化的流程——六阶段审计、对抗性验证、机器可读的发现记录——把"模型说这里有问题"变成"这里有源码证据、有可复现路径、有优先级排序的确认漏洞"。

你会学到什么

  • 六阶段安全审计流程:从侦察到目标中立报告
  • 对抗性验证的设计原则(检查者永远不是发现者)
  • 三种 verdict 的区别:confirmed / needs_validation / rejected
  • 覆盖率账本(coverage-ledger)如何让多轮审计结果可累加
  • 沙箱要求:为什么"不能执行目标代码"时只能标 needs_validation

前提知识

  • 使用过 Claude Code 或类似 coding agent 和 skill 机制
  • 了解基本的安全审计概念(攻击面、信任边界、漏洞确认)
  • Node.js 基础使用经验

项目背景

概述

这个 skill 是 Cloudflare 漏洞发现 harness 的单仓库起点。Cloudflare 在官方博客 Build your own vulnerability harness 里描述了这套系统如何演进成多阶段、覆盖整个 fleet 的漏洞发现平台,而 security-audit 就是它最早的单仓库版本。

它不是"生成一个安全报告"的 prompt 模板,而是一个编排系统:用隔离的子 Agent 跑侦察、狩猎、验证、核实,每一步的产出都有结构化的记录和独立的校验器。

项目信息

  • 组织: Cloudflare
  • 主要语言: JavaScript(校验器零依赖,用 Node.js 写)
  • 许可证: MIT
  • 创建时间: 2026-06-18

项目数据

  • ⭐ GitHub Stars: 13,825+
  • 🍴 Forks: 740+
  • 📄 许可证: MIT
  • 📅 创建时间: 2026-06-18

快速上手

安装

<span># 用 Skills CLI 安装</span>
npx skills add https://github.com/cloudflare/security-audit-skill \
  --skill security-audit

<span># 用户级安装</span>
npx skills add https://github.com/cloudflare/security-audit-skill \
  --skill security-audit \
  --global

使用

启动你的 coding agent,指向要审计的代码库,然后说:

security audit <span>this</span> codebase

或者:

find security vulnerabilities in ./src

<span>do</span> a security review, output to ~<span>/audits/my</span>-project

当请求匹配触发词(security audit / find vulnerabilities / pen-test 等)时,skill 自动激活。

两种模式

模式触发条件行为
**guidance**安全问题、聚焦审查、方法论咨询只使用相关部分,不跑全流程,不写文件
**full audit**明确要求审计/渗透测试、端到端审查跑完整六阶段,写报告文件

核心:六阶段审计流程

Phase 1:侦察(Reconnaissance)

并行启动多个 research Agent,每个返回结构化的源码事实(带 file:line 引用):

  • Agent 1a:产品类型、技术栈、构建命令、子系统边界
  • Agent 1b:主体(principal)、权限、信任边界、控制点
  • Agent 1c:入口面、副本、sink(数据汇点)

产出 architecture.md(架构图)和 coverage-ledger.json(覆盖率账本)。侦察阶段只读,不接触外部服务。

Phase 2:覆盖率导向的漏洞狩猎

根据账本把"覆盖率单元"分配给隔离的 general Agent。每个 hunter 只读自己负责的源码块,只写自己的 scratch/ 目录,返回一个结构化结果。

关键:coverage critic 会找出狩猎覆盖的缺口——哪些单元被漏掉了、哪些分配有重叠。

Phase 3:候选独立验证

每个唯一候选(去重后)交给一个全新的、没有狩猎过它的 verifier,试图证伪它。

验证器的 prompt 明确说:"你没有写这个候选,尝试从源码和有边界的本地证据反驳它。"

Phase 4:结构化输出

写出三种 verdict 的记录到 findings.json,并用 validate-findings.cjs 校验。

Phase 5:独立记录核实

全新的 Agent 核实最终源码声明。如果有实质性替换,替换后的内容再交给另一个独立 verifier。

Phase 6:目标中立报告

从已验证的记录和覆盖率账本,派生出 REPORT.mdFINDINGS-DETAIL.mdNEEDS-VALIDATION.md


三种 Verdict:语义清晰

这是 security-audit 设计上最值得学习的地方——verdict 不是"高中低风险",而是"证据完整度"

Verdict含义
`confirmed`有完整的源码 trace,有有界可复现的观察结果
`needs_validation`有一个精确的未解决事实,但**没有标注严重度**
`rejected`一个被证伪的候选(记录了为什么否定它)

关键原则:"有一个源码证据支撑的疑点" ≠ "确认漏洞"。当一个 lead 因为沙箱限制无法执行验证时,它保持 needs_validation,而不是被草率地标成 confirmed 或丢弃。


设计原则

1. 对抗性验证

检查发现的那个 Agent,永远不是发现它的那个 Agent。这防止了模型"自我确认"——它自己发现的问题,自己又验证一遍,往往会倾向于确认。

2. 严重度需要影响

严重度 = 可能性 × 影响,而不是"偏离了 checklist 多少"。一个符合清单但无实际影响的问题,不是漏洞。

3. 纵深防御缺口不是漏洞

如果 Layer A 已经阻止了攻击,Layer B 的缺失只是一个加固建议(hardening note),不是漏洞。

4. 多轮运行提升覆盖率

Cloudflare 的实测:单轮运行找到的漏洞,大约只有多轮运行累计找到的一半。所以 skill 设计成"对同一仓库的多次运行是可累加的"——每轮用上一轮的账本和发现来定位缺口。


覆盖率账本:让审计可累加

coverage-ledger.json 是这个 skill 的核心数据资产。

普通的安全审计是一次性的——跑一遍,出一份报告,下次再跑等于从零开始。security-audit 的账本让审计可增量

第一轮审计:
  → 生成 coverage-ledger.json(记录哪些单元已覆盖、哪些确认、哪些存疑)
  → 找到 N 个漏洞

第二轮审计(同一仓库):
  → 读取上一轮的账本和 findings
  → 只针对<span>"未覆盖的缺口"</span>和<span>"变更的源码"</span>重新狩猎
  → 把<span>"当前源码仍有证据支撑"</span>的旧发现携带过来
  → 不把<span>"过时或未解决的旧发现"</span>当作已覆盖

每个单元有状态:planned(计划)→ in_progress(进行中)→ completed(完成)/ deferred(因预算推迟)。如果一个单元因为 agent 数量限制无法分配,它被显式标记为 deferred,而不是被静默丢弃。


机器可读的发现记录

findings.json 遵循 report-schema.json 定义的 schema,配合零依赖的校验器:

文件作用
`report-schema.json`三种 verdict 的 JSON schema
`validate-findings.cjs`零依赖校验器(Phase 4/5 用)
`validate-coverage-ledger.cjs`覆盖率账本校验器(Phase 1-5 用)

父 Agent 在创建账本后、每次更新账本后都会跑 validate-coverage-ledger.cjs;在 Phase 4 和每次 Phase 5 替换后跑 validate-findings.cjs

这个"机器可读 + 独立校验"的设计,让审计产出可以接入下游工具链,而不是一份只能人看的 PDF。


沙箱要求:一个诚实的边界

security-audit 明确要求:执行目标控制的代码,必须在 OS 强制的沙箱里

沙箱必须:

  • 禁止外部网络
  • 使用净化的 allowlist 环境
  • 强制资源限制
  • 只允许写入指定的 scratch 路径

如果这些控制不可用,工作流不执行目标代码,把 lead 保持为 needs_validation

这是一个很诚实的工程决策:宁可不确认,也不在没有安全边界的情况下运行可能恶意的代码。在 AI 安全审计工具里,这种对"验证边界"的明确态度,比"我能自动跑 PoC"更值得信任。


参考资源


总结

security-audit 代表了一个判断:AI 安全审计的瓶颈不在"模型能不能发现漏洞",而在"发现的结果能不能被信任"

三点值得注意:

对抗性验证是可信度的核心。 很多 AI 审计工具的问题,是发现和验证由同一个模型完成——模型找到的"漏洞",模型自己再验证一遍,天然有确认偏差。security-audit 用"检查者≠发现者"的结构化约束,把这种偏差从流程层面切掉。

Verdict 语义 = 证据完整度,不是风险等级。 confirmed / needs_validation / rejected 三个状态描述的是"证据链到哪一步断了",而不是"这个问题多严重"。严重度(可能性×影响)是 confirmed 内部的一个字段。这种分离让审计结果可以被机器处理,也能被安全团队信任。

覆盖率的可累加性解决了"审计是一次性的"这个老问题。 传统安全审计做完就过时了。security-audit 的覆盖率账本让审计变成可增量的:每次跑都建立在之前的覆盖基础上,只补缺口、只重验变更。这更接近"持续安全"而非"周期性审计"。

如果你在用 coding agent 做安全相关工作,或者想理解如何让 AI 产出的安全结论变得可信,security-audit 是目前最完整的开源参考。


探索 PrimeSkills —— 精选 AI agent 和技能工具,每一个都经过真实工作流验证。没有炒作,只有真正好用的工具。

访问我的个人主页,获取更多见解和有趣的产品。