Claude
Skills
Sign in
Back

zeroize-audit

Included with Lifetime
$97 forever

Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C/C++/Rust code handling secrets, keys, passwords, or other sensitive data.

Backend & APIs

What this skill does


# zeroize-audit — Claude Skill

## When to Use
- Auditing cryptographic implementations (keys, seeds, nonces, secrets)
- Reviewing authentication systems (passwords, tokens, session data)
- Analyzing code that handles PII or sensitive credentials
- Verifying secure cleanup in security-critical codebases
- Investigating memory safety of sensitive data handling

## When NOT to Use
- General code review without security focus
- Performance optimization (unless related to secure wiping)
- Refactoring tasks not related to sensitive data
- Code without identifiable secrets or sensitive values

---

## Purpose
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:
- Assembly-level analysis for register spills and stack retention
- Data-flow tracking for secret copies
- Heap allocator security warnings
- Semantic IR analysis for loop unrolling and SSA form
- Control-flow graph analysis for path coverage verification
- Runtime validation test generation

## Scope
- Read-only against the target codebase (does not modify audited code; writes analysis artifacts to a temporary working directory).
- Produces a structured report (JSON).
- Requires valid build context (`compile_commands.json`) and compilable translation units.
- "Optimized away" findings only allowed with compiler evidence (IR/asm diff).

---

## Inputs

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 | `null` | Path 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) |

---

## Prerequisites

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` | 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 |

**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 `cargo check`. Use `--json` for machine-readable output, `--manifest` to also validate the crate builds. |
| `{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 |

**Common prerequisite:**

| Prerequisite | Failure mode if missing |
|---|---|
| `{baseDir}/tools/generate_poc.py` | Fail fast — PoC generation is mandatory |

---

## Approved Wipe APIs

The following are recognized as valid zeroization. Configure additional entries in `{baseDir}/configs/`.

**C/C++**
- `explicit_bzero`
- `memset_s`
- `SecureZeroMemory`
- `OPENSSL_cleanse`
- `sodium_memzero`
- Volatile wipe loops (pattern-based; see `volatile_wipe_patterns` in `{baseDir}/configs/default.yaml`)
- In IR: `llvm.memset` with volatile flag, volatile stores, or non-elidable wipe call

**Rust**
- `zeroize::Zeroize` trait (`zeroize()` method)
- `Zeroizing<T>` wrapper (drop-based)
- `ZeroizeOnDrop` derive macro

---

## Finding Capabilities

Findings 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 
Files: 1
Size: 20.6 KB
Complexity: 30/100
Category: Backend & APIs

Related in Backend & APIs