Skip to main content
Audit C/C++/Rust code for missing zeroization of sensitive data and detect compiler-removed memory wiping through assembly-level analysis. Essential for cryptographic implementations and systems handling secrets.

Overview

The Zeroize Audit plugin performs comprehensive analysis to ensure sensitive data is properly cleared from memory:
  • Source-level detection - Missing zeroization, partial wipes, incorrect sizes
  • Compiler optimization analysis - Dead-store elimination removing security-critical wipes
  • Assembly verification - Stack retention and register spills with proof
  • Control-flow analysis - Zeroization missing on error paths
  • Proof-of-concept validation - Every finding backed by working exploit code
This plugin requires buildable code with compile_commands.json (C/C++) or Cargo.toml (Rust) and performs read-only analysis - it does not modify your codebase.

When to Use

Crypto Implementations

Keys, seeds, nonces, secrets in cryptographic code

Authentication Systems

Passwords, tokens, session data, credentials

PII Handling

Personal information requiring secure cleanup

Security Audits

Verifying secure memory handling in security-critical code

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

Supported Languages

C/C++

Requirements:
  • compile_commands.json (generate with CMake or Bear)
  • clang on PATH for IR/assembly analysis
  • Buildable translation units
Generate compile database:

Rust

Requirements:
  • Cargo.toml in crate root
  • cargo +nightly for MIR/LLVM IR emission
  • uv for running analysis scripts
  • Crate must pass cargo check
Preflight validation:

Analysis Pipeline

The plugin uses an 11-agent architecture across 8 phases:
1

Phase 0: Preflight

Validates toolchain, compile DB, creates working directory, enumerates translation units
2

Phase 1: Source Analysis

Wave 1: MCP resolver (C/C++ only, semantic context)Wave 2a: Source analyzer (C/C++, parallel)Wave 2b: Rust source analyzer (Rustdoc JSON + dangerous APIs, parallel)Produces: MISSING_SOURCE_ZEROIZE, PARTIAL_WIPE, SECRET_COPY, INSECURE_HEAP_ALLOC
3

Phase 2: Compiler Analysis

Wave 3: Per-TU compiler analyzer (C/C++, N parallel)Wave 3R: Rust compiler analyzer (MIR, LLVM IR, assembly)Produces: OPTIMIZED_AWAY_ZEROIZE, STACK_RETENTION, REGISTER_SPILL, LOOP_UNROLLED_INCOMPLETE
4

Phase 3: Interim Report

Report assembler collects findings from all agents, applies confidence gates
5

Phase 4: PoC Generation

Generates bespoke proof-of-concept programs for each finding (C/C++ all categories; Rust: MISSING_SOURCE_ZEROIZE, SECRET_COPY, PARTIAL_WIPE)
6

Phase 5: PoC Validation

Compiles and runs PoCs, verifies each proves its claimed vulnerability, presents failures to user
7

Phase 6: Final Report

Merges PoC validation results, produces comprehensive markdown report + structured JSON
8

Phase 7: Test Generation (Optional)

Generates runtime validation test harnesses

Finding Categories

Source-Level Findings

No zeroization found in source code for sensitive object.Evidence required: Source analysis onlyPoC support: Yes (C/C++ + Rust)Example:
Zeroization with incorrect size or incomplete coverage.Evidence required: Source analysis onlyPoC support: Yes (C/C++ + Rust)Example:
Sensitive data copied without zeroization tracking.Evidence required: Source + MCP semantic analysis preferredPoC support: Yes (C/C++ + Rust)Example:
Secret uses insecure allocator instead of secure_malloc.Evidence required: Source analysis onlyPoC support: Yes (C/C++ only)Example:

Compiler-Level Findings

Compiler removed zeroization via dead-store elimination.Evidence required: IR diff (O0 vs O1/O2) showing wipe removal - NEVER valid without compiler evidencePoC support: YesExample IR evidence:
Stack frame may retain secrets after function return.Evidence required:
  • C/C++: Assembly showing secret bytes on stack at ret
  • Rust: LLVM IR alloca + lifetime.end without volatile store; assembly corroboration upgrades to confirmed
PoC support: Yes (C/C++ only)Example:
Secrets spilled from registers to stack without cleanup.Evidence required:
  • C/C++: Assembly showing spill instruction
  • Rust: LLVM IR load + non-zeroize call; assembly corroboration upgrades to confirmed
PoC support: Yes (C/C++ only)Example:
Error-handling paths lack cleanup that normal paths have.Evidence required: CFG or MCP analysisPoC support: YesExample:

Approved Zeroization APIs

C/C++

Rust

Usage Examples

C/C++ Analysis

Rust Analysis

Mixed C/C++ + Rust

Confidence Gating

Evidence Requirements

A finding requires 2+ independent signals for confirmed confidence:
1

1 Signal

Mark as likely - requires review
2

2+ Signals

Mark as confirmed - high confidence
3

0 Strong Signals

Mark as needs_review - name pattern only
Signals include:
  • Name pattern match (e.g., secret_key, password)
  • Type hint match (e.g., uint8_t key[32])
  • Explicit annotation or comment
  • IR evidence (wipe present at O0, absent at O2)
  • Assembly evidence (stack/register not cleared)
  • MCP cross-reference (semantic analysis)
  • CFG evidence (path analysis)
  • PoC validation (exploit proves vulnerability)

Hard Evidence Requirements

These findings are NEVER valid without specified evidence:
  • OPTIMIZED_AWAY_ZEROIZE - Requires IR diff
  • STACK_RETENTION - Requires assembly excerpt
  • REGISTER_SPILL - Requires assembly excerpt

PoC Validation Impact

Output Format

Each run produces two outputs:

1. final-report.md (Human-Readable)

Rust-Specific Analysis

Source Layer (Rustdoc JSON)

Detection patterns:

MIR Layer

Detection patterns:

LLVM IR Layer

Detection patterns:

Assembly Layer (Optional)

Corroboration patterns:
AArch64 Support: Experimental - findings require manual verification. The plugin uses check_rust_asm_aarch64.py for ARM64 analysis.

Direct Tool Usage

C/C++

Rust

Fix Recommendations

Apply in order of preference:
  1. Platform-specific secure APIs
  2. Crypto library APIs
  3. C11 secure memset
  4. Volatile loop with barrier
  5. Rust zeroize crate

Rationalizations to Reject

The plugin rejects these common arguments:
  • “The compiler won’t optimize this away” - Always verify with IR evidence
  • “This is in a hot path” - Benchmark first; security over premature optimization
  • “Stack-allocated secrets are automatically cleaned” - Stack frames may persist
  • “memset is sufficient” - Standard memset can be optimized away
  • “We only handle this data briefly” - Duration is irrelevant; always zeroize
  • “This isn’t a real secret” - If it matches detection heuristics, audit it
  • “We’ll fix it later” - Emit the finding now, don’t defer

References

  • Plugin reference documentation in skills/zeroize-audit/references/
  • Detection strategy guide: references/detection-strategy.md
  • MCP analysis guide: references/mcp-analysis.md
  • IR analysis guide: references/ir-analysis.md
  • PoC generation guide: references/poc-generation.md
  • Rust patterns guide: references/rust-zeroization-patterns.md
Author: Trail of BitsVersion: 0.1.0MCP Integration: Serena (optional, for C/C++ semantic analysis)