关于 security-audit
Security Audit 是一项与 Agent 平台无关的源代码优先安全审查技能,聚焦跨越真实信任边界的漏洞。它区分针对性调查与明确要求的完整审计,并为执行和审计产物规定严格控制。
主要功能
- 01基于信任边界的漏洞审查
- 02指导与完整审计模式
- 03六阶段完整审计流程
- 04目标代码执行的沙箱要求
- 05证据与产物的受控处理
适用场景
- 01调查疑似漏洞
- 02按要求审计整个代码库
- 03整理可复现的安全发现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ cloudflare/ security-audit-skill --skill security-audit安装后在 Claude Code 中输入/security-audit确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
AI-AND-LLM.mdATTACK-CLASSES.mdCLIENT-SIDE.mdCLOUD-AND-DEPLOYMENT.mdDATA-ISOLATION-AND-LIFECYCLE.mdDESKTOP-MOBILE-AND-LOCAL-IPC.mdHUNTING.mdMEMORY-SAFETY-AND-BINARY.mdPROTOCOLS-RPC-AND-MESSAGING.mdRECONNAISSANCE.mdreport-schema.jsonRESOURCE-EXHAUSTION-AND-AVAILABILITY.mdSUPPLY-CHAIN-AND-RELEASE.mdvalidate-coverage-ledger.cjsvalidate-coverage-ledger.test.cjsvalidate-findings.cjsvalidate-findings.test.cjsVALIDATION-AND-REPORTING.mdWEB-PROTOCOL-AND-AUTH.md详细介绍
安全审计
查找违反真实信任边界的漏洞,然后向负责人提供源码证据、安全的复现方法、优先级以及最小有效修复方案。这是一种防御性、以源码为先的工作流程。如果候选问题没有明确受影响的主体、资源或安全后果,则不能视为已确认的发现。
运行模式
本技能默认作为指导使用。加载该技能并不授权执行完整的审计工作流程,也不授权创建文件。
- 指导模式:用于安全问题咨询、专项审查、方法论、分诊或针对特定发现的调查时,只使用本技能中相关的部分。不要自动运行全部六个阶段,不要创建输出目录,也不要写入审计产物。在有用时可以启动专项 Agent;它们会将结果返回给当前任务。
- 完整审计模式:当用户明确要求审计或渗透测试代码库,要求全面、完整或端到端的安全审查,或要求报告产物时,使用完整工作流程。运行全部六个阶段,并写入下文定义的文件。
如果请求可能对应两种模式,应先提出一个聚焦的问题,然后再创建文件或启动完整工作流程。
平台术语
本技能与具体 Agent 平台无关:
- Parent 是协调本次运行并管理共享状态的 Agent。
- Task tool 是平台的委派或子 Agent 机制。
researchagent 是用于专项源码探索和事实验证的委派 Agent。generalagent 是用于广泛调查和有边界的本地执行的委派 Agent。- 标题中的
subagent_type:用于说明由这两种委派 Agent 角色中的哪一种执行该工作。
使用等效的平台能力,同时保持角色、写入隔离、提示词和独立性边界。
通用执行安全
以下规则适用于两种运行模式。源码检查是只读的。只有在操作系统强制执行的沙箱内,才能运行由目标控制的构建、测试、进程、浏览器、模拟器、模糊测试器以及夹具处理,且该沙箱必须提供以下全部控制:
- 无外部网络;仅当检查需要本地客户端/服务端通信时,才使用隔离的 loopback 命名空间;
- 空环境变量,仅从显式白名单中填入安全取值,并使用沙箱本地的
HOME、临时目录和缓存; - 目标和工具链只读,目标控制的进程只能写入其分配的
scratch/目录; - 明确的低 CPU、内存、进程数、文件大小、磁盘和挂钟时间限制。
在沙箱外,Agent 可以在其分配的 scratch/ 目录中创建一次性源码副本,以便构建过程必须在源码旁写入文件时使用。在指导模式下,不得保留目标控制的文件。在完整审计模式下,只有受信任的 parent 侧代码可以按照写入隔离下的流程,将最小的非机密结果提升为保留的 artifacts/。绝不能向目标代码暴露任何保留的输出目录(Agent 自己分配的 scratch/ 除外)、其他 Agent 的目录、宿主机的 home 目录、凭据、套接字或共享服务。不要安装依赖,也不要让构建过程去拉取依赖。仅使用本地已有的工具和依赖。如果无法强制执行全部控制,则不要执行目标代码:应将缺失的沙箱能力报告为需要验证的阻塞项,并给出安全的验证方案。
使用虚拟主体、夹具和机密。不要探测已部署的端点、外部服务、共享基础设施、生产环境身份、其他用户的数据或在线控制平面。不要针对在线或共享进程测试可用性,不要发布产物,不要变更发布版本,不要消耗付费 API 配额,也不要超出确认缺陷所需的最小本地影响范围继续操作。如果决定性事实位于源码或沙箱夹具之外,应将其报告为需要验证。
完整审计设置
在完整审计模式下,正式开始侦察前先确定以下各项值:
- Skill 目录:包含此
SKILL.md的绝对目录。 - 审计目标:被审计代码仓库的绝对根目录。
- 仓库名称:从目录名或本地 Git 远程地址中获得的稳定仓库标识符。
- 输出目录:位于目标之外的一个新的可写目录,默认为
~/security-audit-skill/<repo-name>/run-<N>,其中<N>为下一个未使用的整数。仅当用户明确选择目录位于目标内部,且父进程验证版本控制会忽略整个目录时,才可使用目标内的目录。否则应停止并请求提供外部路径。 - 源码引用:所审计的提交,以及工作区是否有未提交修改。不要把未审阅的生成文件或已修改文件视为另一个修订版本。
写入隔离
父进程负责创建共享运行文件,并且是这些文件的唯一写入者:
run-metadata.jsonarchitecture.mdcoverage-ledger.jsonfindings.jsonREPORT.mdFINDINGS-DETAIL.mdNEEDS-VALIDATION.md
每个 hunter 或 verifier 都会获得位于 <output-dir>/agents/<agent-id>/ 下的唯一根目录,并拥有独立的 scratch/ 和 artifacts/ 目录。规范的 agent ID 须匹配 ^[a-z0-9][a-z0-9_-]{0,63}$,且不得等于 Windows 设备名,例如 con、prn、aux、nul、com1 至 com9,或 lpt1 至 lpt9。使用小写 ID 可避免大小写折叠导致的冲突。Agent 以及每个受目标控制的进程只能写入 scratch/;保留的 artifacts/ 由父进程拥有,永远不会暴露给沙箱,并且只能由可信的父端提升代码写入。Agent 不得修改共享文件、目标源码、已保留的 artifacts,或其他 agent 的目录。不得将 /tmp 或宿主机主目录用作可写的后备位置。
执行前,父进程需打开并保留 agent 的 scratch/ 和 artifacts/ 根目录的可信、不可继承目录描述符,并记录预期的 scratch 相对路径产物文件白名单,以及明确的单文件和累计字节上限。绝不能将这些描述符传递给 agent 或沙箱。沙箱及其所有进程终止后,可信的父端代码会逐个提升白名单中的每个文件:
- 验证声明的相对路径:拒绝绝对路径、空路径、
.、..或包含符号链接的组件。 - 从保留的 scratch 根目录描述符出发,使用不跟随链接的目录相对操作逐级遍历每个父组件;绝不通过路径重新打开。
- 以不跟随链接且非阻塞的方式打开叶子节点。
- 使用
fstat验证其为普通文件,链接计数恰好为 1,且大小在记录的单文件和累计字节上限之内。 - 从该描述符读取时再次强制执行这些上限。
- 精确复制已验证的大小,再次执行
fstat,若身份、类型、链接计数或大小发生变化则拒绝。 - 对于目标位置,从保留的 artifacts 根目录描述符出发,使用不跟随链接的目录相对操作逐级遍历每个父组件;要求每个已存在的组件都是真实目录,缺失的目录则以独占方式创建,然后不跟随链接重新打开并验证。
- 以独占方式创建叶子文件且不跟随链接,验证打开的目标为链接计数恰好为 1 的普通文件,并从已验证的源描述符复制,不重新打开任一路径。
- 在非 POSIX 系统上使用等效的抗竞争 API。
- 绝不递归复制或通配 scratch,绝不将归档解压到 artifacts 中,也绝不打开或提升符号链接、FIFO、套接字、设备、目录、硬链接文件、正在变化的文件,或超出上限的文件。
- 如果任何检查不可用、无法强制执行或失败,则丢弃该 scratch 条目;若它是决定性证据,则以
needs_validation保留,并注明确切的提升阻断原因。 HUNTING.md 和 VALIDATION-AND-REPORTING.md 将此流程以同一个代码块的形式分别写入 hunter 与 verifier 提示词;该代码块所述规则与本列表顺序一致。
对于已复现的检查,记录命令、确切的测试输入、沙箱限制,以及复现所需的、仅限白名单内的环境变量名和安全的非敏感取值。切勿捕获或复制环境变量全集、继承的变量、凭据取值、认证状态或无关的主机路径。应从空环境启动,而不是在执行后尝试脱敏。
委派之前,父进程需写入 run-metadata.json,内容至少包括 run_id、repo、target、source_ref、profile、scope_paths、budget(未设置时为 null)、execution_policy: "sandboxed-source-and-local-only"、所选配套文件、先前运行的路径、共享文件的负责人,以及 run_status: "in_progress"。仅当这些事实发生变化时才更新元数据;候选状态应记录在覆盖账本和 findings.json 中。
完整审计规划
本节中关于覆盖范围、先前运行和配置文件的要求以及预算要求,仅适用于完整审计模式。
覆盖范围与先前运行
单次扫描无法构成完整审计。在开始挖掘之前,需制定确定性的覆盖计划,并在每次收到 agent 结果后更新。RECONNAISSANCE.md 定义了稳定的覆盖单元,HUNTING.md 定义了覆盖评审波次。只有父进程可以更新账本。
若存在先前运行,则在规划本次运行之前,需读取所有兼容的 coverage-ledger.json 和 findings.json:
- 将当前相关源码与每条先前记录及单元进行比对。仅有先前的源码引用,并不能证明某路径未发生变化。
- 只有当某条先前
confirmed记录的相关源码与条件未发生变化,且其证据仍满足当前契约时,才可将其纳入本次候选集。将其关联到一个初始状态为planned的当前账本单元,保留其指纹,仅将该被沿用的根因排除在 hunter 之外,并将该记录送入本次最终验证流程;负责重新检查它的第 3 阶段 verifier 将成为该单元的任务负责人,并将其状态改为candidate。 - 当某条先前
confirmed记录的相关源码发生变化时,需创建一个当前planned的复验单元。不要将该记录加入 hunter 排除列表。只有当前独立验证确认了当前路径与结果,它才会保持confirmed状态。 - 先前状态为
needs_validation、deferred、blocked、out_of_scope的单元,以及源码已变化的单元,均需作为当前工作处理。仍处于外部依赖状态的needs_validation记录,仅可在检查当前源码追踪并按指纹关联到一个当前planned单元后沿用;该单元需由 verifier 的复查提供负责人与证据,且记录应保留未解决的阻塞项。这些先前状态均不得抑制当前单元。 - 先前同一源码下已覆盖的单元可用于确定优先级,但仍需在当前账本中可见。先前
rejected的记录仅抑制未变化的失败结论,不抑制其所在单元的覆盖;若证据发生变化,则需创建当前工作。 - 阅读先前的配置文件与范围。先前
quick或限定范围的账本,只贡献其记录的证据与缺口,绝不能推出"其余部分无需关注"的结论。
若不存在先前账本,需在最终覆盖声明中予以说明。切勿暗示单次运行即可穷尽目标。
运行配置与范围
在完整审计的设置阶段,根据用户的请求选择一个配置,或根据目标的规模和重要程度提出一个配置建议。将其记录在 run-metadata.json(profile、scope_paths)中,并在报告中说明。默认配置为 standard。
quick:针对小型目标、重复运行或快速初步查看的有限范围检查。将台账单元粗化为 surface × boundary × attack class(subsystem 使用固定的规范标识符profile/quick/all-in-scope-subsystems),仅运行一轮 hunter 和随后一轮 final coverage-critic 检查,并且对每个候选项使用一个全新的 verifier,同时用于候选验证和最终记录验证。不要启动后续的 hunter 轮次:将 critic 接受的新发现和重新分配记录为deferred。standard:按原文所述的工作流执行。deep:适用于高风险或大型目标。按 subsystem 和生命周期模式拆分台账单元,运行 critic 轮次直至通过且无新问题,候选验证与最终记录验证保持为独立的全新 Agent,并对prior_covered_same_source单元进行独立的第二轮检查。
范围限定运行仅审计其中的一个子集:指定路径、一个 subsystem、一个配套领域,或两个源引用之间的差异。仅为范围内的 surface 生成台账单元,其余内容一律记录为 out_of_scope,绝不记为 covered。范围限定运行或 quick 运行必须在报告中明确表明自身为部分覆盖。
配置只改变覆盖广度与冗余程度,不改变证据标准。不得因规模调整而削弱候选门禁、源码/本地执行边界、needs_validation 处理规则、schema 校验,以及对 confirmed 记录的独立验证。
成本预算
账本使成本可计量:一个单位大致相当于一次 hunter 分派,一个存活候选项则根据配置文件需要一到两次 verifier 分派。当用户设定预算(或父 Agent 为大型目标提议预算)时,请在 run-metadata.json 中记录 budget,其值为所有阶段中 Agent 调用次数的上限。
在启动任何侦察 Agent 之前,先应用严格预算门控。需预留四次基线侦察调用、quick 模式下的一次波次后最终 critic,或 standard/deep 模式下的一次波次后 critic 加一次独立的最终干净 critic,以及至少一次 verifier 调用。只有在为每次额外调用重复执行本门控之后,才能增加针对性侦察。如果所请求的预算无法覆盖这一最低要求,则不启动任何 Agent:请求更大的预算、更窄的范围或其他配置文件。若请求保持不变,则将 run_status 设为 "incomplete",incomplete_reason 设为 "budget_cannot_fund_reconnaissance_and_reserves",并报告未执行任何审计轮次。
按以下顺序使用预算:
- 将侦察、每个波次后 critic 以及独立的最终干净 critic 均计为 Agent 调用。
- 在狩猎之前预留 critic 与验证成本。 对于
quick,预留其一次波次后最终 critic。在每个standard或deep的 hunter 波次之前,预留一次紧随其后的波次后 critic,以及一次独立的最终干净 critic。同时根据配置文件预留 verifier 成本(每个预期候选项约 1 或 2 个 Agent;拿不准时,在扣除 critic 预留后预留余额的 30%)。绝不能将 hunter 分派到这两类预留中。 - 按优先级将 hunter 分配到各单位,直至狩猎配额用尽。在该波次结束后立即使用为其预留的波次后 critic;保持最终干净 critic 与验证预留完好无损。
- 在后续波次开始前,重新为其新的波次后 critic 预留成本。如果剩余预算无法覆盖所需的 critic 调用与验证预留,则不为该波次启动任何 hunter,将其计划单位标记为
deferred,原因为budget_cannot_reserve_critics_and_validation,并使用保留的最终干净 critic 记录由此产生的缺口。
在第一波次之前,应以已播种的单位、推算的 hunter 数量、强制性 critic 调用、验证预留以及剩余预算是否足以覆盖该计划来更新预侦察估算。如果明显无法覆盖,应当直接说明,并提议收窄范围或改用更粗略的配置文件,而不是悄然削减证据。如果后续情况耗尽了所需的最终 critic 预留,则不启动任何 hunter,将所有计划工作标记为 deferred,将运行设为未完成,原因为 critic_budget_exhausted,且不得声称已完成全面覆盖。
严格的总 Agent 预算仍可能因候选项数量异常庞大,或因阶段 5 中需要另一名独立 verifier 的重大替换而被超出。如果剩余预算无法验证所有候选项,则停止狩猎,在预算允许的范围内按指纹顺序验证候选项,并将 run_status 设为 "incomplete",同时将 incomplete_reason 设为 "validation_budget_exhausted"。每个未验证的指纹都必须与一个 candidate 账本单位保持关联,并标注该未解决原因。不得将未验证的候选项放入 findings.json,不得将其重新标记为 needs_validation,也不得将运行报告为已完成。阶段 6 只有在其第一节明确说明候选项验证尚未完成,并列出受影响的指纹和单位时,才可以生成部分报告。切勿悄然超出用户设定的严格预算。
核心原则
要求明确边界与结果
对于每个候选项,都必须说明:较低信任级别的主体、接受的输入或行为、预期的控制措施、跨越的边界、受影响的主体或资源,以及具体观察到的或资源所有者可观察到的结果。不得将缺失的最佳实践、猜测的部署行为、通用解析器崩溃或仅影响自身的问题提升为安全发现。
使用有界的本地证据
静态分析可确定源代码路径。在所有执行控制均可用时,沙箱化本地测试可验证行为:例如最小函数测试框架、现有单元测试、小型解析器测试样例、虚拟租户集成测试、本地渲染的配置,或有界的隔离环回客户端。遇到错误返回值、未授权访问虚拟记录、检测到清理器问题、策略差异或其他最小影响时,立即停止。不得将本地检查扩展到最小边界结果之外,也不得生成持久化、故障后利用或隐匿相关材料。
尊重源代码的可见范围
部署控制、代理行为、服务提供方设置、浏览器标头、身份策略、代理 ACL、打包方式和拓扑都是真实的控制措施。如果仓库中未包含这些措施所需的信息,不要假设它们存在或不存在。使用 needs_validation,明确指出缺失的事实,并提供安全的、由负责人观察或在本地执行的验证计划。
区分优先级与确定性
只有 confirmed 记录才标注严重性。可能性和影响必须反映已演示的条件和结果;总体严重性不得高于已演示的影响。needs_validation 表示某个有明确源码依据的边界假设因条件不足而无法验证,并非低置信度的已确认漏洞,且不标注严重性。
根据以下基准校准总体严重性:
- critical — 未经身份验证的攻击者获得代码执行权限、对整个数据存储的访问权限,或接管任意账户。
- high — 攻击者完全绕过明确的安全控制并造成实际后果:绕过身份验证、跨租户读取或写入、执行影响其他用户的存储型脚本、经身份验证后执行代码,或远程停止共享服务且无需身份验证。
- medium — 确实违反边界,但影响范围有限、前提条件少见,或后果仅限于狭窄的资源集。
- low — 泄露非机密内部信息,或需要持续投入才能获得微小收益。
- informational — 已确认但影响极小的发现,主要可作为更大问题的前置条件。
区分 high 和 medium 的关键:已演示的结果是否完全绕过了某项明确控制,并造成实际后果,还是仅削弱了该控制?如果无法说明具体损害,严重性就应低于直觉判断。
建议采用影响最小且有效的源码修复
对于每项已确认的发现,指出代码必须强制执行的不变量,以及能在最后一个可信决策点强制执行该不变量的最小源码改动。优先提供具体的仓库相对路径变更和回归测试,而非泛泛的加固建议。审计应描述修复方案,不得修改目标源码。
完整审计工作流
在完整审计模式下,按顺序完成全部六个阶段:
- 侦察:借助 RECONNAISSANCE.md,梳理源码、信任边界、本地构建路径、伴随组件选择、既有证据,并生成初始的确定性覆盖台账。
- 以覆盖为导向的多轮挖掘:根据台账分配相互隔离的挖掘者,并借助 HUNTING.md、ATTACK-CLASSES.md 以及所选的领域伴随组件,收集结构化的候选结果。
- 候选验证:按 VALIDATION-AND-REPORTING.md 的定义,汇总指纹,并将每个候选交给一个全新的源码验证者。
- 结构化输出:将所有最终的
confirmed、needs_validation和rejected记录写入findings.json;使用report-schema.json和validate-findings.cjs进行验证,并使用validate-coverage-ledger.cjs验证覆盖声明。 - 独立记录核验:使用全新的 Agent 核验最终的源码结论,并核对更正或状态变更。
- 与目标无关的报告:基于最终记录生成
REPORT.md、FINDINGS-DETAIL.md和NEEDS-VALIDATION.md,且不包含任何实时探测说明。
在进入以下两种终态之一之前,不得结束本次运行:(a) 所有第 6 阶段产物均已写入,且两个验证器均通过;或 (b) 已记录 run_status: "incomplete" 及其确切原因,并在报告中披露该缺口。切勿在阶段中途停止。
反模式
- 将检查清单偏差当作漏洞上报。
- 在没有可达边界违规的情况下给出纵深防御建议。
- 在有界本地证据已足够的情况下,仍进行实时或共享环境测试。
- 对源码中不存在的提供方、代理、浏览器、身份或部署行为进行猜测。
- 将预期的同一主体授权或仅影响自身的情形,视为跨边界结果。
- 上报比实际观察到的效果更强的解析器或运行时影响。
- 提交无法去重或验证的纯文字挖掘结果。
- 重复上报已携带的同源既有已确认记录,或将其用作锚定挖掘方向的示例。
- 为
needs_validation记录指定严重程度。 - 在独立验证之前撰写报告,或让文字与 JSON 不一致。