zeroize-audit by trailofbits/skills
npx skills add https://github.com/trailofbits/skills --skill zeroize-audit检测源代码中敏感数据缺失的归零操作,并识别被编译器优化(例如,无用存储消除)移除或削弱的归零操作,必须提供 LLVM IR/汇编证据。能力包括:
compile_commands.json)和可编译的翻译单元。完整模式请参见 {baseDir}/schemas/input.json。关键字段:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 字段 | 必需 | 默认值 | 描述 |
|---|
path | 是 | — | 仓库根目录 |
compile_db | 否 | null | 用于 C/C++ 分析的 compile_commands.json 路径。如果未设置 cargo_manifest,则必需。 |
cargo_manifest | 否 | null | 用于 Rust crate 分析的 Cargo.toml 路径。如果未设置 compile_db,则必需。 |
config | 否 | — | 定义启发式规则和已批准擦除操作的 YAML 文件 |
opt_levels | 否 | ["O0","O1","O2"] | 用于 IR 比较的优化级别。O1 是诊断级别:如果擦除在 O1 消失,则是简单的无用存储消除;O2 能捕获更激进的消除。 |
languages | 否 | ["c","cpp","rust"] | 要分析的语言 |
max_tus | 否 | — | 从编译数据库处理的翻译单元数量限制 |
mcp_mode | 否 | prefer | off、prefer 或 require — 控制 Serena MCP 的使用 |
mcp_required_for_advanced | 否 | true | 当 MCP 不可用时,将 SECRET_COPY、MISSING_ON_ERROR_PATH 和 NOT_DOMINATING_EXITS 降级为 needs_review |
mcp_timeout_ms | 否 | — | MCP 语义查询的超时预算 |
poc_categories | 否 | 全部 11 个可利用类别 | 为其生成概念验证的发现类别。C/C++ 发现:支持全部 11 个类别。Rust 发现:仅支持 MISSING_SOURCE_ZEROIZE、SECRET_COPY 和 PARTIAL_WIPE;其他 Rust 类别标记为 poc_supported=false。 |
poc_output_dir | 否 | generated_pocs/ | 生成的概念验证输出目录 |
enable_asm | 否 | true | 启用汇编生成和分析(步骤 8);产生 STACK_RETENTION、REGISTER_SPILL。如果 emit_asm.sh 缺失,则自动禁用。 |
enable_semantic_ir | 否 | false | 启用语义 LLVM IR 分析(步骤 9);产生 LOOP_UNROLLED_INCOMPLETE |
enable_cfg | 否 | false | 启用控制流图分析(步骤 10);产生 MISSING_ON_ERROR_PATH、NOT_DOMINATING_EXITS |
enable_runtime_tests | 否 | false | 启用运行时测试框架生成(步骤 11) |
运行前,请验证以下各项。每项都有定义的失败模式。
C/C++ 先决条件:
| 先决条件 | 缺失时的失败模式 |
|---|---|
compile_db 路径下的 compile_commands.json | 快速失败 — 不继续执行 |
PATH 环境变量中的 clang | 快速失败 — IR/ASM 分析无法进行 |
PATH 环境变量中的 uvx(用于 Serena) | 如果 mcp_mode=require:失败。如果 mcp_mode=prefer:继续执行但不使用 MCP;根据置信度门控规则降级受影响的发现。 |
{baseDir}/tools/extract_compile_flags.py | 快速失败 — 无法提取每个翻译单元的编译标志 |
{baseDir}/tools/emit_ir.sh | 快速失败 — IR 分析无法进行 |
{baseDir}/tools/emit_asm.sh | 警告并跳过汇编发现(STACK_RETENTION, REGISTER_SPILL) |
{baseDir}/tools/mcp/check_mcp.sh | 警告并视为 MCP 不可用 |
{baseDir}/tools/mcp/normalize_mcp_evidence.py | 警告并使用原始 MCP 输出 |
Rust 先决条件:
| 先决条件 | 缺失时的失败模式 |
|---|---|
cargo_manifest 路径下的 Cargo.toml | 快速失败 — 不继续执行 |
cargo check 通过 | 快速失败 — crate 必须可构建 |
PATH 环境变量中的 cargo +nightly | 快速失败 — 生成 MIR 和 LLVM IR 需要 nightly 版本 |
PATH 环境变量中的 uv | 快速失败 — 运行 Python 分析脚本所需 |
{baseDir}/tools/validate_rust_toolchain.sh | 警告 — 手动运行预检。检查所有工具、脚本、nightly 版本,并可选择检查 cargo check。使用 --json 获取机器可读输出,使用 --manifest 同时验证 crate 构建。 |
{baseDir}/tools/emit_rust_mir.sh | 快速失败 — MIR 分析无法进行(支持 --opt、--crate、--bin/--lib;--out 可以是文件或目录) |
{baseDir}/tools/emit_rust_ir.sh | 快速失败 — LLVM IR 分析无法进行(需要 --opt;支持 --crate、--bin/--lib;--out 必须是 .ll 文件) |
{baseDir}/tools/emit_rust_asm.sh | 警告并跳过汇编发现(STACK_RETENTION、REGISTER_SPILL)。支持 --opt、--crate、--bin/--lib、--target、--intel-syntax;--out 可以是 .s 文件或目录。 |
{baseDir}/tools/diff_rust_mir.sh | 警告并跳过 MIR 级优化比较。接受 2 个或更多 MIR 文件,进行规范化、成对差异比较,并报告归零/析构胶水模式首次消失的优化级别。 |
{baseDir}/tools/scripts/semantic_audit.py | 警告并跳过语义源代码分析 |
{baseDir}/tools/scripts/find_dangerous_apis.py | 警告并跳过危险 API 扫描 |
{baseDir}/tools/scripts/check_mir_patterns.py | 警告并跳过 MIR 分析 |
{baseDir}/tools/scripts/check_llvm_patterns.py | 警告并跳过 LLVM IR 分析 |
{baseDir}/tools/scripts/check_rust_asm.py | 警告并跳过 Rust 汇编分析(STACK_RETENTION、REGISTER_SPILL、析构胶水检查)。分派给 check_rust_asm_x86.py(生产环境)或 check_rust_asm_aarch64.py(实验性 — AArch64 发现需要手动验证)。 |
{baseDir}/tools/scripts/check_rust_asm_x86.py | check_rust_asm.py 进行 x86-64 分析所需;如果缺失则警告并跳过 |
{baseDir}/tools/scripts/check_rust_asm_aarch64.py | check_rust_asm.py 进行 AArch64 分析所需(实验性);如果缺失则警告并跳过 |
通用先决条件:
| 先决条件 | 缺失时的失败模式 |
|---|---|
{baseDir}/tools/generate_poc.py | 快速失败 — 概念验证生成是强制性的 |
以下被识别为有效的归零操作。在 {baseDir}/configs/ 中配置其他条目。
C/C++
explicit_bzeromemset_sSecureZeroMemoryOPENSSL_cleansesodium_memzero{baseDir}/configs/default.yaml 中的 volatile_wipe_patterns)llvm.memset、易失性存储或不可消除的擦除调用Rust
zeroize::Zeroize 特质(zeroize() 方法)Zeroizing<T> 包装器(基于析构)ZeroizeOnDrop 派生宏发现按所需证据分组。仅尝试所需工具可用的发现。
| 发现 ID | 描述 | 所需条件 | 概念验证支持 |
|---|---|---|---|
MISSING_SOURCE_ZEROIZE | 源代码中未找到归零操作 | 仅源代码 | 是(C/C++ + Rust) |
PARTIAL_WIPE | 大小不正确或不完整的擦除 | 仅源代码 | 是(C/C++ + Rust) |
NOT_ON_ALL_PATHS | 在某些控制流路径上缺少归零操作(启发式) | 仅源代码 | 是(仅限 C/C++) |
SECRET_COPY | 敏感数据被复制但未跟踪归零操作 | 源代码 + 优先使用 MCP | 是(C/C++ + Rust) |
INSECURE_HEAP_ALLOC | 机密使用不安全的分配器(malloc 与 secure_malloc) | 仅源代码 | 是(仅限 C/C++) |
OPTIMIZED_AWAY_ZEROIZE | 编译器移除了归零操作 | 需要 IR 差异(从不单独使用源代码) | 是 |
STACK_RETENTION | 返回后栈帧可能保留机密 | 需要汇编(C/C++);LLVM IR alloca+lifetime.end 证据(Rust);汇编佐证可升级为 confirmed | 是(仅限 C/C++) |
REGISTER_SPILL | 机密从寄存器溢出到栈 | 需要汇编(C/C++);LLVM IR load+调用点证据(Rust);汇编佐证可升级为 confirmed | 是(仅限 C/C++) |
MISSING_ON_ERROR_PATH | 错误处理路径缺少清理 | 需要 CFG 或 MCP | 是 |
NOT_DOMINATING_EXITS | 擦除操作不支配所有退出点 | 需要 CFG 或 MCP | 是 |
LOOP_UNROLLED_INCOMPLETE | 展开的循环擦除不完整 | 需要语义 IR | 是 |
分析流水线在 8 个阶段中使用 11 个代理,由协调器({baseDir}/prompts/task.md)通过 Task 调用。代理将持久化的发现文件写入共享工作目录(/tmp/zeroize-audit-{run_id}/),从而实现并行执行并防止上下文压力。
| 代理 | 阶段 | 目的 | 输出目录 |
|---|---|---|---|
0-preflight | 阶段 0 | 预检检查(工具、工具链、编译数据库、crate 构建)、配置合并、工作目录创建、翻译单元枚举 | {workdir}/ |
1-mcp-resolver | 阶段 1,第 1 波(仅限 C/C++) | 通过 Serena MCP 解析符号、类型和跨文件引用 | mcp-evidence/ |
2-source-analyzer | 阶段 1,第 2a 波(仅限 C/C++) | 识别敏感对象、检测擦除操作、验证正确性、数据流/堆分析 | source-analysis/ |
2b-rust-source-analyzer | 阶段 1,第 2b 波(仅限 Rust,与 2a 并行) | Rustdoc JSON 特质感知分析 + 危险 API 搜索 | source-analysis/ |
3-tu-compiler-analyzer | 阶段 2,第 3 波(仅限 C/C++,N 个并行) | 每个翻译单元的 IR 差异、汇编、语义 IR、CFG 分析 | compiler-analysis/{tu_hash}/ |
3b-rust-compiler-analyzer | 阶段 2,第 3R 波(仅限 Rust,单个代理) | Crate 级别的 MIR、LLVM IR 和汇编分析 | rust-compiler-analysis/ |
4-report-assembler | 阶段 3(临时)+ 阶段 6(最终) | 收集所有代理的发现,应用置信度门控;合并概念验证结果并生成最终报告 | report/ |
5-poc-generator | 阶段 4 | 制作定制的概念验证程序(C/C++:所有类别;Rust:MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE) | poc/ |
5b-poc-validator | 阶段 5 | 编译并运行所有概念验证 | poc/ |
5c-poc-verifier | 阶段 5 | 验证每个概念验证是否证明了其声称的发现 | poc/ |
6-test-generator | 阶段 7(可选) | 生成运行时验证测试框架 | tests/ |
协调器一次从 {baseDir}/workflows/ 读取一个每阶段工作流文件,并维护 orchestrator-state.json 以便在上下文压缩后恢复。代理通过文件路径(config_path)接收配置,而不是通过值。
Phase 0: 0-preflight agent — Preflight + config + create workdir + enumerate TUs
→ writes orchestrator-state.json, merged-config.yaml, preflight.json
Phase 1: Wave 1: 1-mcp-resolver (skip if mcp_mode=off OR language_mode=rust)
Wave 2a: 2-source-analyzer (C/C++ only; skip if no compile_db) ─┐ parallel
Wave 2b: 2b-rust-source-analyzer (Rust only; skip if no cargo_manifest) ─┘
Phase 2: Wave 3: 3-tu-compiler-analyzer x N (C/C++ only; parallel per TU)
Wave 3R: 3b-rust-compiler-analyzer (Rust only; single crate-level agent)
Phase 3: Wave 4: 4-report-assembler (mode=interim → findings.json; reads all agent outputs)
Phase 4: Wave 5: 5-poc-generator (C/C++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE; other Rust findings: poc_supported=false)
Phase 5: PoC Validation & Verification
Step 1: 5b-poc-validator agent (compile and run all PoCs)
Step 2: 5c-poc-verifier agent (verify each PoC proves its claimed finding)
Step 3: Orchestrator presents verification failures to user via AskUserQuestion
Step 4: Orchestrator merges all results into poc_final_results.json
Phase 6: Wave 6: 4-report-assembler (mode=final → merge PoC results, final-report.md)
Phase 7: Wave 7: 6-test-generator (optional)
Phase 8: Orchestrator — Return final-report.md
ID 按代理进行命名空间划分,以防止并行执行期间发生冲突:
| 实体 | 模式 | 分配者 |
|---|---|---|
| 敏感对象(C/C++) | SO-0001–SO-4999 | 2-source-analyzer |
| 敏感对象(Rust) | SO-5000–SO-9999(Rust 命名空间) | 2b-rust-source-analyzer |
| 源代码发现(C/C++) | F-SRC-NNNN | 2-source-analyzer |
| 源代码发现(Rust) | F-RUST-SRC-NNNN | 2b-rust-source-analyzer |
| IR 发现(C/C++) | F-IR-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| ASM 发现(C/C++) | F-ASM-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| CFG 发现 | F-CFG-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| 语义 IR 发现 | F-SIR-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| Rust MIR 发现 | F-RUST-MIR-NNNN | 3b-rust-compiler-analyzer |
| Rust LLVM IR 发现 | F-RUST-IR-NNNN | 3b-rust-compiler-analyzer |
| Rust 汇编发现 | F-RUST-ASM-NNNN | 3b-rust-compiler-analyzer |
| 翻译单元 | TU-{hash} | 协调器 |
| 最终发现 | ZA-NNNN | 4-report-assembler |
每个发现 JSON 对象都包含 related_objects、related_findings 和 evidence_files 字段,用于在代理之间进行交叉引用。
分析分两个阶段运行。完整的逐步指南,请参见 {baseDir}/references/detection-strategy.md。
| 阶段 | 步骤 | 产生的发现 | 所需工具 |
|---|---|---|---|
| 阶段 1(源代码) | 1–6 | MISSING_SOURCE_ZEROIZE, PARTIAL_WIPE, NOT_ON_ALL_PATHS, SECRET_COPY, INSECURE_HEAP_ALLOC | 源代码 + 编译数据库 |
| 阶段 2(编译器) | 7–12 | OPTIMIZED_AWAY_ZEROIZE, STACK_RETENTION ,REGISTER_SPILL, LOOP_UNROLLED_INCOMPLETE†, MISSING_ON_ERROR_PATH‡, NOT_DOMINATING_EXITS‡ | clang, IR/ASM 工具 |
enable_asm=true(默认) † 需要 enable_semantic_ir=true ‡ 需要 enable_cfg=true每次运行产生两个输出:
final-report.md — 全面的 Markdown 报告(主要的人类可读输出)findings.json — 结构化 JSON,匹配 {baseDir}/schemas/output.json(供机器使用和下游工具处理)Markdown 报告(final-report.md)包含以下部分:
findings.json 文件遵循 {baseDir}/schemas/output.json 中的模式。每个 Finding 对象:
{
"id": "ZA-0001",
"category": "OPTIMIZED_AWAY_ZEROIZE",
"severity": "high",
"confidence": "confirmed",
"language": "c",
"file": "src/crypto.c",
"line": 42,
"symbol": "key_buf",
"evidence": "store volatile i8 0 count: O0=32, O2=0 — wipe eliminated by DSE",
"compiler_evidence": {
"opt_levels": ["O0", "O2"],
"o0": "32 volatile stores targeting key_buf",
"o2": "0 volatile stores (all eliminated)",
"diff_summary": "All volatile wipe stores removed at O2 — classic DSE pattern"
},
"suggested_fix": "Replace memset with explicit_bzero or add compiler_fence(SeqCst) after the wipe",
"poc": {
"file": "generated_pocs/ZA-0001.c",
"makefile_target": "ZA-0001",
"compile_opt": "-O2",
"requires_manual_adjustment": false,
"validated": true,
"validation_result": "exploitable"
}
}
完整模式和枚举值请参见 {baseDir}/schemas/output.json。
一个发现需要至少 2 个独立信号 才能标记为 confirmed。有 1 个信号时,标记为 likely。有 0 个强信号(仅名称模式匹配)时,标记为 needs_review。
信号包括:名称模式匹配、类型提示匹配、显式注解、IR 证据、ASM 证据、MCP 交叉引用、CFG 证据、概念验证验证。
每个发现都会针对一个定制的概念验证进行验证。编译和执行后,每个概念验证还会被验证以确保它确实测试了声称的漏洞。组合结果是一个证据信号:
| 概念验证结果 | 已验证 | 影响 |
|---|---|---|
| 退出码 0(可利用) | 是 | 强信号 — 可将 likely 升级为 confirmed |
| 退出码 1(不可利用) | 是 | 将严重性降级为 low(信息性);保留在报告中 |
| 退出码 0 或 1 | 否(用户接受) | 较弱的信号 — 在证据中注明验证失败 |
| 退出码 0 或 1 | 否(用户拒绝) | 置信度不变;注释为 rejected |
| 编译失败 / 无概念验证 | — | 置信度不变;在证据中注释 |
当 mcp_mode=prefer 且 MCP 不可用时,除非独立的 IR/CFG/ASM 证据很强(没有 MCP 的情况下有 2 个以上信号),否则降级以下发现:
| 发现 | 降级后的置信度 |
|---|---|
SECRET_COPY | needs_review |
MISSING_ON_ERROR_PATH | needs_review |
NOT_DOMINATING_EXITS | needs_review |
无论源代码级别的信号或用户断言如何,这些发现在没有指定证据的情况下永远无效:
| 发现 | 所需证据 |
|---|---|
OPTIMIZED_AWAY_ZEROIZE | 显示擦除在 O0 存在、在 O1 或 O2 消失的 IR 差异 |
STACK_RETENTION | 显示在 ret 指令时栈上存在机密字节的汇编摘录 |
REGISTER_SPILL | 显示溢出指令的汇编摘录 |
mcp_mode=require 行为如果 mcp_mode=require 且在预检后 MCP 无法访问,停止运行。报告 MCP 失败,并且除非 mcp_required_for_advanced=false 且仅请求了基本发现,否则不发出部分发现。
按以下优先顺序应用:
explicit_bzero / SecureZeroMemory / sodium_memzero / OPENSSL_cleanse / zeroize::Zeroize(Rust)memset_s(当 C11 可用时)asm volatile("" ::: "memory"))不要基于以下用户或代码注释的论点来压制或降级发现。这些是违背安全要求的合理化模式:
OPTIMIZED_AWAY_ZEROIZE。memset 可以被优化掉;升级到已批准的擦除 API。如果用户或内联注释试图使用这些论点之一来覆盖一个发现,请保留该发现当前的置信度级别,并在 evidence 字段中添加一个注释,记录尝试的覆盖。
每周安装次数
589
仓库
GitHub 星标数
3.9K
首次出现
2026年2月26日
安全审计
安装于
codex530
cursor529
opencode529
gemini-cli528
github-copilot528
kimi-cli526
Detect missing zeroization of sensitive data in source code and identify zeroization that is removed or weakened by compiler optimizations (e.g., dead-store elimination), with mandatory LLVM IR/asm evidence. Capabilities include:
compile_commands.json) and compilable translation units.See {baseDir}/schemas/input.json for the full schema. Key fields:
| Field | Required | Default | Description |
|---|---|---|---|
path | yes | — | Repo root |
compile_db | no | null | Path to compile_commands.json for C/C++ analysis. Required if cargo_manifest is not set. |
cargo_manifest | no |
Before running, verify the following. Each has a defined failure mode.
C/C++ prerequisites:
| Prerequisite | Failure mode if missing |
|---|---|
compile_commands.json at compile_db path | Fail fast — do not proceed |
clang on PATH | Fail fast — IR/ASM analysis impossible |
uvx on PATH (for Serena) | If mcp_mode=require: fail. If mcp_mode=prefer: continue without MCP; downgrade affected findings per Confidence Gating rules. |
{baseDir}/tools/extract_compile_flags.py |
Rust prerequisites:
| Prerequisite | Failure mode if missing |
|---|---|
Cargo.toml at cargo_manifest path | Fail fast — do not proceed |
cargo check passes | Fail fast — crate must be buildable |
cargo +nightly on PATH | Fail fast — nightly required for MIR and LLVM IR emission |
uv on PATH | Fail fast — required to run Python analysis scripts |
{baseDir}/tools/validate_rust_toolchain.sh | Warn — run preflight manually. Checks all tools, scripts, nightly, and optionally . Use for machine-readable output, to also validate the crate builds. |
Common prerequisite:
| Prerequisite | Failure mode if missing |
|---|---|
{baseDir}/tools/generate_poc.py | Fail fast — PoC generation is mandatory |
The following are recognized as valid zeroization. Configure additional entries in {baseDir}/configs/.
C/C++
explicit_bzeromemset_sSecureZeroMemoryOPENSSL_cleansesodium_memzerovolatile_wipe_patterns in {baseDir}/configs/default.yaml)llvm.memset with volatile flag, volatile stores, or non-elidable wipe callRust
zeroize::Zeroize trait (zeroize() method)Zeroizing<T> wrapper (drop-based)ZeroizeOnDrop derive macroFindings are grouped by required evidence. Only attempt findings for which the required tooling is available.
| Finding ID | Description | Requires | PoC Support |
|---|---|---|---|
MISSING_SOURCE_ZEROIZE | No zeroization found in source | Source only | Yes (C/C++ + Rust) |
PARTIAL_WIPE | Incorrect size or incomplete wipe | Source only | Yes (C/C++ + Rust) |
NOT_ON_ALL_PATHS | Zeroization missing on some control-flow paths (heuristic) | Source only | Yes (C/C++ only) |
SECRET_COPY | Sensitive data copied without zeroization tracking | Source + MCP preferred |
The analysis pipeline uses 11 agents across 8 phases, invoked by the orchestrator ({baseDir}/prompts/task.md) via Task. Agents write persistent finding files to a shared working directory (/tmp/zeroize-audit-{run_id}/), enabling parallel execution and protecting against context pressure.
| Agent | Phase | Purpose | Output Directory |
|---|---|---|---|
0-preflight | Phase 0 | Preflight checks (tools, toolchain, compile DB, crate build), config merge, workdir creation, TU enumeration | {workdir}/ |
1-mcp-resolver | Phase 1, Wave 1 (C/C++ only) | Resolve symbols, types, and cross-file references via Serena MCP | mcp-evidence/ |
2-source-analyzer | Phase 1, Wave 2a (C/C++ only) | Identify sensitive objects, detect wipes, validate correctness, data-flow/heap |
The orchestrator reads one per-phase workflow file from {baseDir}/workflows/ at a time, and maintains orchestrator-state.json for recovery after context compression. Agents receive configuration by file path (config_path), not by value.
Phase 0: 0-preflight agent — Preflight + config + create workdir + enumerate TUs
→ writes orchestrator-state.json, merged-config.yaml, preflight.json
Phase 1: Wave 1: 1-mcp-resolver (skip if mcp_mode=off OR language_mode=rust)
Wave 2a: 2-source-analyzer (C/C++ only; skip if no compile_db) ─┐ parallel
Wave 2b: 2b-rust-source-analyzer (Rust only; skip if no cargo_manifest) ─┘
Phase 2: Wave 3: 3-tu-compiler-analyzer x N (C/C++ only; parallel per TU)
Wave 3R: 3b-rust-compiler-analyzer (Rust only; single crate-level agent)
Phase 3: Wave 4: 4-report-assembler (mode=interim → findings.json; reads all agent outputs)
Phase 4: Wave 5: 5-poc-generator (C/C++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE; other Rust findings: poc_supported=false)
Phase 5: PoC Validation & Verification
Step 1: 5b-poc-validator agent (compile and run all PoCs)
Step 2: 5c-poc-verifier agent (verify each PoC proves its claimed finding)
Step 3: Orchestrator presents verification failures to user via AskUserQuestion
Step 4: Orchestrator merges all results into poc_final_results.json
Phase 6: Wave 6: 4-report-assembler (mode=final → merge PoC results, final-report.md)
Phase 7: Wave 7: 6-test-generator (optional)
Phase 8: Orchestrator — Return final-report.md
IDs are namespaced per agent to prevent collisions during parallel execution:
| Entity | Pattern | Assigned By |
|---|---|---|
| Sensitive object (C/C++) | SO-0001–SO-4999 | 2-source-analyzer |
| Sensitive object (Rust) | SO-5000–SO-9999 (Rust namespace) | 2b-rust-source-analyzer |
| Source finding (C/C++) | F-SRC-NNNN |
Every finding JSON object includes related_objects, related_findings, and evidence_files fields for cross-referencing between agents.
Analysis runs in two phases. For complete step-by-step guidance, see {baseDir}/references/detection-strategy.md.
| Phase | Steps | Findings produced | Required tooling |
|---|---|---|---|
| Phase 1 (Source) | 1–6 | MISSING_SOURCE_ZEROIZE, PARTIAL_WIPE, NOT_ON_ALL_PATHS, SECRET_COPY, INSECURE_HEAP_ALLOC | Source + compile DB |
| Phase 2 (Compiler) | 7–12 | OPTIMIZED_AWAY_ZEROIZE, STACK_RETENTION , †, ‡, ‡ |
enable_asm=true (default) † requires enable_semantic_ir=true ‡ requires enable_cfg=trueEach run produces two outputs:
final-report.md — Comprehensive markdown report (primary human-readable output)findings.json — Structured JSON matching {baseDir}/schemas/output.json (for machine consumption and downstream tools)The markdown report (final-report.md) contains these sections:
The findings.json file follows the schema in {baseDir}/schemas/output.json. Each Finding object:
{
"id": "ZA-0001",
"category": "OPTIMIZED_AWAY_ZEROIZE",
"severity": "high",
"confidence": "confirmed",
"language": "c",
"file": "src/crypto.c",
"line": 42,
"symbol": "key_buf",
"evidence": "store volatile i8 0 count: O0=32, O2=0 — wipe eliminated by DSE",
"compiler_evidence": {
"opt_levels": ["O0", "O2"],
"o0": "32 volatile stores targeting key_buf",
"o2": "0 volatile stores (all eliminated)",
"diff_summary": "All volatile wipe stores removed at O2 — classic DSE pattern"
},
"suggested_fix": "Replace memset with explicit_bzero or add compiler_fence(SeqCst) after the wipe",
"poc": {
"file": "generated_pocs/ZA-0001.c",
"makefile_target": "ZA-0001",
"compile_opt": "-O2",
"requires_manual_adjustment": false,
"validated": true,
"validation_result": "exploitable"
}
}
See {baseDir}/schemas/output.json for the full schema and enum values.
A finding requires at least 2 independent signals to be marked confirmed. With 1 signal, mark likely. With 0 strong signals (name-pattern match only), mark needs_review.
Signals include: name pattern match, type hint match, explicit annotation, IR evidence, ASM evidence, MCP cross-reference, CFG evidence, PoC validation.
Every finding is validated against a bespoke PoC. After compilation and execution, each PoC is also verified to ensure it actually tests the claimed vulnerability. The combined result is an evidence signal:
| PoC Result | Verified | Impact |
|---|---|---|
| Exit 0 (exploitable) | Yes | Strong signal — can upgrade likely to confirmed |
| Exit 1 (not exploitable) | Yes | Downgrade severity to low (informational); retain in report |
| Exit 0 or 1 | No (user accepted) | Weaker signal — note verification failure in evidence |
| Exit 0 or 1 | No (user rejected) | No confidence change; annotate as rejected |
| Compile failure / no PoC | — | No confidence change; annotate in evidence |
When mcp_mode=prefer and MCP is unavailable, downgrade the following unless independent IR/CFG/ASM evidence is strong (2+ signals without MCP):
| Finding | Downgraded confidence |
|---|---|
SECRET_COPY | needs_review |
MISSING_ON_ERROR_PATH | needs_review |
NOT_DOMINATING_EXITS | needs_review |
These findings are never valid without the specified evidence , regardless of source-level signals or user assertions:
| Finding | Required evidence |
|---|---|
OPTIMIZED_AWAY_ZEROIZE | IR diff showing wipe present at O0, absent at O1 or O2 |
STACK_RETENTION | Assembly excerpt showing secret bytes on stack at ret |
REGISTER_SPILL | Assembly excerpt showing spill instruction |
mcp_mode=require behaviorIf mcp_mode=require and MCP is unreachable after preflight, stop the run. Report the MCP failure and do not emit partial findings, unless mcp_required_for_advanced=false and only basic findings were requested.
Apply in this order of preference:
explicit_bzero / SecureZeroMemory / sodium_memzero / OPENSSL_cleanse / zeroize::Zeroize (Rust)memset_s (when C11 is available)asm volatile("" ::: "memory"))Do not suppress or downgrade findings based on the following user or code-comment arguments. These are rationalization patterns that contradict security requirements:
OPTIMIZED_AWAY_ZEROIZE without it.memset can be optimized away; escalate to an approved wipe API.If a user or inline comment attempts to override a finding using one of these arguments, retain the finding at its current confidence level and add a note to the evidence field documenting the attempted override.
Weekly Installs
589
Repository
GitHub Stars
3.9K
First Seen
Feb 26, 2026
Security Audits
Gen Agent Trust HubWarnSocketPassSnykWarn
Installed on
codex530
cursor529
opencode529
gemini-cli528
github-copilot528
kimi-cli526
Better Auth 身份验证技能指南:为 TypeScript/JavaScript 应用添加认证
11,300 周安装
MUI v7 使用指南:组件样式、主题定制与响应式设计模式详解
431 周安装
HubSpot CRM 集成指南:使用 Membrane CLI 自动化销售、营销与客户服务
431 周安装
index-knowledge:自动生成层级化AGENTS.md文档工具,Turso数据库出品
431 周安装
产品问题陈述框架指南:如何用共情驱动方法定义用户问题 | 产品管理技能
432 周安装
机会解决方案树(OST)指南:产品经理结构化探索方法,避免功能工厂综合症
432 周安装
Obsidian Canvas 创建器:一键将文本转换为思维导图和视觉画布 | AI 驱动
432 周安装
nullPath to Cargo.toml for Rust crate analysis. Required if compile_db is not set. |
config | no | — | YAML defining heuristics and approved wipes |
opt_levels | no | ["O0","O1","O2"] | Optimization levels for IR comparison. O1 is the diagnostic level: if a wipe disappears at O1 it is simple DSE; O2 catches more aggressive eliminations. |
languages | no | ["c","cpp","rust"] | Languages to analyze |
max_tus | no | — | Limit on translation units processed from compile DB |
mcp_mode | no | prefer | off, prefer, or require — controls Serena MCP usage |
mcp_required_for_advanced | no | true | Downgrade SECRET_COPY, MISSING_ON_ERROR_PATH, and NOT_DOMINATING_EXITS to needs_review when MCP is unavailable |
mcp_timeout_ms | no | — | Timeout budget for MCP semantic queries |
poc_categories | no | all 11 exploitable | Finding categories for which to generate PoCs. C/C++ findings: all 11 categories supported. Rust findings: only MISSING_SOURCE_ZEROIZE, SECRET_COPY, and PARTIAL_WIPE are supported; other Rust categories are marked poc_supported=false. |
poc_output_dir | no | generated_pocs/ | Output directory for generated PoCs |
enable_asm | no | true | Enable assembly emission and analysis (Step 8); produces STACK_RETENTION, REGISTER_SPILL. Auto-disabled if emit_asm.sh is missing. |
enable_semantic_ir | no | false | Enable semantic LLVM IR analysis (Step 9); produces LOOP_UNROLLED_INCOMPLETE |
enable_cfg | no | false | Enable control-flow graph analysis (Step 10); produces MISSING_ON_ERROR_PATH, NOT_DOMINATING_EXITS |
enable_runtime_tests | no | false | Enable runtime test harness generation (Step 11) |
| Fail fast — cannot extract per-TU flags |
{baseDir}/tools/emit_ir.sh | Fail fast — IR analysis impossible |
{baseDir}/tools/emit_asm.sh | Warn and skip assembly findings (STACK_RETENTION, REGISTER_SPILL) |
{baseDir}/tools/mcp/check_mcp.sh | Warn and treat as MCP unavailable |
{baseDir}/tools/mcp/normalize_mcp_evidence.py | Warn and use raw MCP output |
cargo check--json--manifest{baseDir}/tools/emit_rust_mir.sh | Fail fast — MIR analysis impossible (--opt, --crate, --bin/--lib supported; --out can be file or directory) |
{baseDir}/tools/emit_rust_ir.sh | Fail fast — LLVM IR analysis impossible (--opt required; --crate, --bin/--lib supported; --out must be .ll) |
{baseDir}/tools/emit_rust_asm.sh | Warn and skip assembly findings (STACK_RETENTION, REGISTER_SPILL). Supports --opt, --crate, --bin/--lib, --target, --intel-syntax; --out can be .s file or directory. |
{baseDir}/tools/diff_rust_mir.sh | Warn and skip MIR-level optimization comparison. Accepts 2+ MIR files, normalizes, diffs pairwise, and reports first opt level where zeroize/drop-glue patterns disappear. |
{baseDir}/tools/scripts/semantic_audit.py | Warn and skip semantic source analysis |
{baseDir}/tools/scripts/find_dangerous_apis.py | Warn and skip dangerous API scan |
{baseDir}/tools/scripts/check_mir_patterns.py | Warn and skip MIR analysis |
{baseDir}/tools/scripts/check_llvm_patterns.py | Warn and skip LLVM IR analysis |
{baseDir}/tools/scripts/check_rust_asm.py | Warn and skip Rust assembly analysis (STACK_RETENTION, REGISTER_SPILL, drop-glue checks). Dispatches to check_rust_asm_x86.py (production) or check_rust_asm_aarch64.py (EXPERIMENTAL — AArch64 findings require manual verification). |
{baseDir}/tools/scripts/check_rust_asm_x86.py | Required by check_rust_asm.py for x86-64 analysis; warn and skip if missing |
{baseDir}/tools/scripts/check_rust_asm_aarch64.py | Required by check_rust_asm.py for AArch64 analysis (EXPERIMENTAL); warn and skip if missing |
| Yes (C/C++ + Rust) |
INSECURE_HEAP_ALLOC | Secret uses insecure allocator (malloc vs. secure_malloc) | Source only | Yes (C/C++ only) |
OPTIMIZED_AWAY_ZEROIZE | Compiler removed zeroization | IR diff required (never source-only) | Yes |
STACK_RETENTION | Stack frame may retain secrets after return | Assembly required (C/C++); LLVM IR alloca+lifetime.end evidence (Rust); assembly corroboration upgrades to confirmed | Yes (C/C++ only) |
REGISTER_SPILL | Secrets spilled from registers to stack | Assembly required (C/C++); LLVM IR load+call-site evidence (Rust); assembly corroboration upgrades to confirmed | Yes (C/C++ only) |
MISSING_ON_ERROR_PATH | Error-handling paths lack cleanup | CFG or MCP required | Yes |
NOT_DOMINATING_EXITS | Wipe doesn't dominate all exits | CFG or MCP required | Yes |
LOOP_UNROLLED_INCOMPLETE | Unrolled loop wipe is incomplete | Semantic IR required | Yes |
source-analysis/ |
2b-rust-source-analyzer | Phase 1, Wave 2b (Rust only, parallel with 2a) | Rustdoc JSON trait-aware analysis + dangerous API grep | source-analysis/ |
3-tu-compiler-analyzer | Phase 2, Wave 3 (C/C++ only, N parallel) | Per-TU IR diff, assembly, semantic IR, CFG analysis | compiler-analysis/{tu_hash}/ |
3b-rust-compiler-analyzer | Phase 2, Wave 3R (Rust only, single agent) | Crate-level MIR, LLVM IR, and assembly analysis | rust-compiler-analysis/ |
4-report-assembler | Phase 3 (interim) + Phase 6 (final) | Collect findings from all agents, apply confidence gates; merge PoC results and produce final report | report/ |
5-poc-generator | Phase 4 | Craft bespoke proof-of-concept programs (C/C++: all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE) | poc/ |
5b-poc-validator | Phase 5 | Compile and run all PoCs | poc/ |
5c-poc-verifier | Phase 5 | Verify each PoC proves its claimed finding | poc/ |
6-test-generator | Phase 7 (optional) | Generate runtime validation test harnesses | tests/ |
2-source-analyzer| Source finding (Rust) | F-RUST-SRC-NNNN | 2b-rust-source-analyzer |
| IR finding (C/C++) | F-IR-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| ASM finding (C/C++) | F-ASM-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| CFG finding | F-CFG-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| Semantic IR finding | F-SIR-{tu_hash}-NNNN | 3-tu-compiler-analyzer |
| Rust MIR finding | F-RUST-MIR-NNNN | 3b-rust-compiler-analyzer |
| Rust LLVM IR finding | F-RUST-IR-NNNN | 3b-rust-compiler-analyzer |
| Rust assembly finding | F-RUST-ASM-NNNN | 3b-rust-compiler-analyzer |
| Translation unit | TU-{hash} | Orchestrator |
| Final finding | ZA-NNNN | 4-report-assembler |
REGISTER_SPILLLOOP_UNROLLED_INCOMPLETEMISSING_ON_ERROR_PATHNOT_DOMINATING_EXITSclang, IR/ASM tools |