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
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)clangon PATH for IR/assembly analysis- Buildable translation units
Rust
Requirements:Cargo.tomlin crate rootcargo +nightlyfor MIR/LLVM IR emissionuvfor running analysis scripts- Crate must pass
cargo check
Analysis Pipeline
The plugin uses an 11-agent architecture across 8 phases:Phase 0: Preflight
Validates toolchain, compile DB, creates working directory, enumerates translation units
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_ALLOCPhase 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_INCOMPLETEPhase 3: Interim Report
Report assembler collects findings from all agents, applies confidence gates
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)
Phase 5: PoC Validation
Compiles and runs PoCs, verifies each proves its claimed vulnerability, presents failures to user
Phase 6: Final Report
Merges PoC validation results, produces comprehensive markdown report + structured JSON
Finding Categories
Source-Level Findings
MISSING_SOURCE_ZEROIZE
MISSING_SOURCE_ZEROIZE
No zeroization found in source code for sensitive object.Evidence required: Source analysis onlyPoC support: Yes (C/C++ + Rust)Example:
PARTIAL_WIPE
PARTIAL_WIPE
Zeroization with incorrect size or incomplete coverage.Evidence required: Source analysis onlyPoC support: Yes (C/C++ + Rust)Example:
SECRET_COPY
SECRET_COPY
Sensitive data copied without zeroization tracking.Evidence required: Source + MCP semantic analysis preferredPoC support: Yes (C/C++ + Rust)Example:
INSECURE_HEAP_ALLOC
INSECURE_HEAP_ALLOC
Secret uses insecure allocator instead of secure_malloc.Evidence required: Source analysis onlyPoC support: Yes (C/C++ only)Example:
Compiler-Level Findings
OPTIMIZED_AWAY_ZEROIZE
OPTIMIZED_AWAY_ZEROIZE
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_RETENTION
STACK_RETENTION
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.endwithout volatile store; assembly corroboration upgrades toconfirmed
REGISTER_SPILL
REGISTER_SPILL
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
MISSING_ON_ERROR_PATH
MISSING_ON_ERROR_PATH
Error-handling paths lack cleanup that normal paths have.Evidence required: CFG or MCP analysisPoC support: YesExample:
Approved Zeroization APIs
C/C++
- Recommended
- Volatile Loop (with barrier)
- LLVM IR Evidence
Rust
Usage Examples
C/C++ Analysis
Rust Analysis
Mixed C/C++ + Rust
Confidence Gating
Evidence Requirements
A finding requires 2+ independent signals forconfirmed confidence:
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
PoC Validation Impact
| PoC Result | Verified | Impact |
|---|---|---|
| Exit 0 (exploitable) | Yes | Upgrade likely → confirmed |
| Exit 1 (not exploitable) | Yes | Downgrade to low severity |
| Exit 0/1 | No (user accepted) | Weaker signal, note verification failure |
| Exit 0/1 | No (user rejected) | No confidence change, mark rejected |
| Compile failure | — | No confidence change, annotate |
Output Format
Each run produces two outputs:1. final-report.md (Human-Readable)
Rust-Specific Analysis
Source Layer (Rustdoc JSON)
Detection patterns:| Pattern | Category | Severity |
|---|---|---|
#[derive(Copy)] on sensitive type | SECRET_COPY | Critical |
No Zeroize/ZeroizeOnDrop/Drop impl | MISSING_SOURCE_ZEROIZE | High |
Partial Drop (not all fields zeroed) | PARTIAL_WIPE | High |
mem::forget / ManuallyDrop::new | MISSING_SOURCE_ZEROIZE | Critical |
ptr::write_bytes without compiler_fence | OPTIMIZED_AWAY_ZEROIZE | Medium |
MIR Layer
Detection patterns:| Pattern | Category | Severity |
|---|---|---|
Drop glue without call zeroize:: | MISSING_SOURCE_ZEROIZE | High |
Yield terminator with live secret local | NOT_ON_ALL_PATHS | High |
| Secret moved into non-Zeroizing aggregate | SECRET_COPY | Medium |
LLVM IR Layer
Detection patterns:| Pattern | Category | Severity |
|---|---|---|
store volatile count drops O0 → O2 | OPTIMIZED_AWAY_ZEROIZE | High |
@llvm.memset without volatile flag | OPTIMIZED_AWAY_ZEROIZE | High |
alloca present at O0, absent at O2 (SROA) | OPTIMIZED_AWAY_ZEROIZE | High |
Assembly Layer (Optional)
Corroboration patterns:| Pattern | Category | Notes |
|---|---|---|
subq $N, %rsp with no zero-store before retq | STACK_RETENTION | x86-64 only |
movq %reg, -N(%rsp) (register spill) | REGISTER_SPILL | Caller-saved registers |
drop_in_place::<T> with no call zeroize | MISSING_SOURCE_ZEROIZE | Monomorphized instances |
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:-
Platform-specific secure APIs
-
Crypto library APIs
-
C11 secure memset
-
Volatile loop with barrier
-
Rust zeroize crate
Rationalizations to Reject
Related Plugins
- Constant-Time Analysis - Timing side-channel detection
- Property-Based Testing - Test crypto invariants
- Testing Handbook Skills - Security testing patterns
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)