mirror of
https://github.com/imjasonh/rustvulncheck
synced 2026-07-06 19:02:25 +00:00
The old --existing-db flag skipped already-enriched entries by advisory ID, so improvements to diff_analyzer.rs had no effect on the committed vuln_db.json. The new --re-enrich flag re-fetches diffs for existing entries and re-extracts symbols using the current code, updating them in-place. The CI enrich job now passes --re-enrich so that code changes to the symbol extraction pipeline are reflected in the PR's vuln_db.json diff. https://claude.ai/code/session_01P1LKP6aqGt68rQAXrF6kSE
3.8 KiB
3.8 KiB
CLAUDE.md
What is this?
rustvulncheck (binary: cargo-deep-audit) is a reachability-based vulnerability scanner for Rust, inspired by Go's govulncheck. Instead of just flagging vulnerable dependencies, it identifies the specific vulnerable functions and checks whether your code actually calls them.
Architecture
Three-phase pipeline:
- Enrich (
cargo-deep-audit enrich): Parses RustSec advisory TOML files, fetches the fixing commit from GitHub, extracts modified function symbols from the diff, and writes an enrichedvuln_db.json. - Analyze (
cargo-deep-audit analyze): Parses a project'sCargo.lock, cross-references locked versions againstvuln_db.json, then scans source files for calls to vulnerable symbols. - CLI: Orchestrates the above via
clapsubcommands.
Key files
src/main.rs— CLI entry point,enrichandanalyzesubcommandssrc/advisory.rs— RustSec TOML parsersrc/diff_analyzer.rs— Extracts function symbols from unified diffssrc/scanner.rs— Finds call sites of vulnerable symbols in source codesrc/type_tracker.rs— Variable type inference (usingsyn) to improve call-site confidencesrc/analyzer.rs— Phase 2 orchestrator: version matching + symbol scanningsrc/github.rs— GitHub API client for fetching patch diffssrc/lockfile.rs—Cargo.lockparsersrc/db.rs—VulnDbserialization/deserializationvuln_db.json— The enriched vulnerability database (642 entries)
Commands
# Build
cargo build
# Run tests
cargo test
# Phase 1: Enrich database from RustSec advisory-db
cargo-deep-audit enrich \
--advisory-db /path/to/advisory-db \
--output vuln_db.json \
--github-token <token> \
[--limit N] [--include-all] [--existing-db existing.json] \
[--re-enrich] [--timeout-secs N]
# Phase 2: Analyze a project
cargo-deep-audit analyze \
--project /path/to/rust/project \
--db vuln_db.json
Test fixtures
tests/fixtures/vulnerable_project/— Golden test, expects 4 reachable vulnstests/fixtures/safe_project/— Expects 0 reachable vulnstests/fixtures/edge_cases_project/— Tests false positives, comments, aliasingtests/fixtures/test_project/— Basic integration test
vuln_db.json structure
{
"generated_at": "unix:<timestamp>",
"entries": [{
"advisory_id": "RUSTSEC-2026-XXXX",
"package": "crate-name",
"title": "...",
"date": "YYYY-MM-DD",
"patched_versions": [">= X.Y.Z"],
"commit_sha": "abc123...",
"vulnerable_symbols": [{
"file": "src/module/file.rs",
"function": "crate::module::Type::method",
"change_type": "Modified|Added|Deleted"
}]
}]
}
Known issues with symbol extraction
The diff-based symbol extraction in diff_analyzer.rs has several known limitations:
<method>placeholders (~90 entries): When the fn declaration is too far from the diff hunk for git to include in the header, the tool falls back toType::<method>which loses precision.forkeyword leaking (~14 entries): Theimpl_reregex's greedy<.*>can over-match nested generics inimpl<T> Trait for Type, causingfor Typeto appear in the symbol (e.g.,instance::for PyObject::from).whereclause leaking (~5 entries): Similar regex issue wherewherebounds bleed into the type capture.- Test functions included (~39 entries):
#[cfg(test)]functions inside library source files pass theis_test_filecheck (which only filters by file path, not attributes). - Missing crate name prefix: For non-workspace repos,
src/foo/bar.rsbecomesfoo::barinstead ofcrate_name::foo::barsince the crate name isn't in the file path. - Empty symbol lists (~495 of 642 entries): Many advisories lack GitHub commit references or the diffs don't yield extractable symbols.