security-audit-skill 台账校验器源码导读:状态不变量如何守护安全审计的单一事实源
2026/9/20 21:34:54 网站建设 项目流程

security-audit-skill 台账校验器源码导读:状态不变量如何守护安全审计的单一事实源

【免费下载链接】security-audit-skillA coding-agent skill for multi-phase security audits with independently verified, machine-readable findings项目地址: https://gitcode.com/GitHub_Trending/se/security-audit-skill

security-audit-skill 是一个面向编程智能体的安全审计技能(coding-agent skill),它将 AI 智能体变成结构化的安全审计员。这篇文章导读其中的核心脚本validate-coverage-ledger.cjs——台账校验器,讲清楚它如何为coverage-ledger.json这本"审计账本"设定状态不变量(state invariants),让多智能体审计的每一步都可验证、可追溯。不需要 Node.js 基础也能读懂。

先搞懂"台账":审计过程中的唯一事实源 📒

整个安全审计分六个阶段(侦察 → 覆盖驱动的猎捕 → 候选验证 → 结构化输出 → 独立复核 → 中立报告)。其中第一阶段的侦察阶段会生成 coverage-ledger.json 台账,后续每个猎手(hunter)智能体的分配、进度、证据都记录在这里。

README 中有一句话点明了校验器的角色:

父智能体在创建台账之后以及每次后续更新台账之后,都会运行validate-coverage-ledger.cjs

也就是说:台账是"谁、审了哪些代码、审到什么程度、留下了什么证据"的单一事实源(single source of truth)。而校验器就是看门人——任何一次更新只要违反规则,立刻被拒。这就是"状态不变量"的由来:无论台账经历多少轮更新,某些逻辑关系必须永远成立

一次校验的完整旅程:五道关卡 🔍

打开 validate-coverage-ledger.cjs(全文 872 行,零依赖),整个流程像一条流水线,输入文件要连闯五道关卡:

关卡函数检查什么
1️⃣ 安全读取readFileWithinLimit拒绝符号链接、FIFO、超大文件、非法 UTF-8
2️⃣ 文本预检preflightJsonTextJSON.parse之前先逐字符扫描结构,防栈溢出
3️⃣ 文档预检preflightDocument对解析后的文档做深度/规模二次复核
4️⃣ 单元级校验collectUnitErrors必填字段、规范 ID、安全路径、状态不变量
5️⃣ 跨单元一致性validateDocument重复 ID、语义冲突、字典序排序

值得注意的两个"防御性"设计:

  • 限制常量集中管理:LIMITS 把"最多 5MB 输入、10000 个顶层单元、每个数组 1000 项、嵌套深度 64、总计 50 万个值"等上限写在一处。测试套件专门构造了 200 万层嵌套的恶意输入来验证:校验器用迭代而非递归实现,绝不会栈溢出,只会报出exceeds nesting depth limit 64
  • 诊断信息自身也要安全:错误消息里出现的控制字符(如终端转义序列、RTL 覆盖符)会被 safeQuote 转义成\uXXXX,错误总数封顶 100 条。一个会回显用户输入的校验器,本身不能成为注入面。

重头戏:状态机与"证据不变量" ⚖️

台账里每个单元(unit)有一个status字段,共 8 种取值(见 STATUSES)。核心校验函数 validateStateInvariants 强制的是一条简单而有力的规则:

状态决定证据——什么状态,就只能有什么证据。

下面这张表就是整个校验器的"灵魂"(要求非空,要求为空,无约束):

状态负责人 agent_id审阅路径 reviewed_paths本地检查 local_checks结果指纹 result_fingerprints未决事实 unresolved
planned已计划必须为 null
in_progress进行中必须非空
blocked受阻必须非空
covered已覆盖必须非空
candidate候选漏洞必须非空
not_applicable/out_of_scope/deferred必须为 null

这张表能防住三类典型"说谎":

  1. 提前报功planned单元必须没有任何证据和负责人。想跳过侦察直接标记covered?对不起,covered要求非空的审阅路径和检查记录。
  2. 证据与结论矛盾covered(已确认安全)却还挂着"未决事实",或blocked(受阻)却给出了结论指纹——都会被拦截。
  3. 指纹越权result_fingerprints是"候选漏洞"的编号,只有candidate状态允许持有,其他状态一律必须为空。

还有一条跨字段不变量由 validateReviewedPathOwnership 保证:单元级的reviewed_paths必须恰好等于它名下所有检查各自reviewed_paths的并集——每行代码的审阅都必须有明确的负责人(agent),而负责人的证据也不得凭空出现在聚合列表之外。

换人机制:attempts 归档与"新鲜负责人" 🔄

多智能体审计有一条铁律(README 称之为Adversarial validation):验证发现的智能体,绝不能是发现它的智能体。当"批评者"(critic)智能体发现某个分配有问题需要重新指派时,校验器强制三件事,规则集中在 validateAttempts:

  • 旧状态必须整体归档进attempts,并递增wave(波次);归档的 wave 必须严格递增,且小于当前 wave;
  • 新负责人必须是"新鲜"的:任何出现在历史尝试里的agent_id都不能再当新负责人,连历史证据(local_checks 里的 owner)也不能挪到当前状态里;
  • 产物不可复用:某次尝试产生的 artifact 文件,之后的尝试不能再次引用。

效果是:重分配永远是"清场重来",旧证据留在档案里,新负责人带着干净的上下文进场。这在 HUNTING.md 的编排规则里与 critic 机制配合,构成了整个工作流的对抗性验证基础。

身份系统:规范 ID、安全路径与 Agent 命名 🪪

除了状态机,还有三套"身份不变量":

  • 规范覆盖 ID(canonical ID):由 canonicalCoverageId 从canonical_refs的四个字段(surface / boundary / subsystem / attack_class)按固定顺序 URL 编码后用::拼接而成。单元里手写的coverage_id必须与之逐字节相等——手写一个"好记的别名"会被直接判错。跨单元层面,校验器还会拒绝重复 ID、拒绝"不同 ID 指向同一语义元组"的别名,并要求全部单元按 ID 字典序排列,方便 diff 与多次运行合并。
  • 安全相对路径:isSafeRelativePath 拒绝绝对路径、..穿越、Windows 保留名(con、prn、com1…)、尾随空格/点号、不可见控制字符等近 20 种写法。
  • Agent 命名:isSafeAgentId 只接受小写字母数字开头、总长 64 以内的 ID,并避开 Windows 设备名。因为 agent_id 会被用来构造agents/<id>/artifacts/产物目录——命名不安全,等于把路径穿越的口子留给了智能体自己。

30 秒上手运行 🚀

校验器就是普通 Node.js 脚本,用法一行(见文件头部注释):

node validate-coverage-ledger.cjs <path-to-coverage-ledger.json>

输出只有两种:全部通过时打印PASS: N coverage units valid(退出码 0);否则逐条打印ERROR:明细并以FAIL: N validation error(s)结尾(退出码 1)。配套测试 validate-coverage-ledger.test.cjs 多达 740 行,其中不乏"敌意"用例:终端控制字符注入、FIFO 管道、符号链接、受限堆内存下的深度嵌套……校验器的每一个防御点都有对应的回归测试。

关键文件速查 📁

文件作用
validate-coverage-ledger.cjs台账校验器本体(872 行,零依赖)
validate-coverage-ledger.test.cjs校验器测试套件,含大量恶意输入用例
HUNTING.md阶段 2 编排规则:critic 重分配、attempts 归档
RECONNAISSANCE.md阶段 1 侦察:台账的诞生
SKILL.md六阶段工作流总览与预算机制
README.md项目说明、文件清单与设计原则

总结:不变量思维给审计工程上了三道锁 🔒

  1. 状态即合同:8 种状态各自绑定明确的证据形态,让"进度"无法与"证据"脱节,机器可判定任何一次台账更新是否诚实;
  2. 换人即清场:attempts 归档 + 新鲜负责人规则,把"自己审自己"从道德约定变成了语法错误;
  3. 校验器自身也要被审计:5MB 上限、迭代式预检、诊断转义、路径白名单——它防的不仅是坏数据,还有坏数据背后的恶意输入。

这正是 README.md 中设计原则的落地:让 AI 智能体做安全审计,前提是审计过程本身必须比被审计对象更可信。

【免费下载链接】security-audit-skillA coding-agent skill for multi-phase security audits with independently verified, machine-readable findings项目地址: https://gitcode.com/GitHub_Trending/se/security-audit-skill

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询