Override Hygiene Auditing
Dependency overrides are security patches you apply manually when a vulnerable transitive package is not yet fixed upstream. They work - but they accumulate debt silently over time. The package gets updated, the CVE gets fixed, the override stays. Or worse: the override was never effective to begin with, and your project has been exposed the entire time without knowing it.
cve-lite . --check-overrides audits your override declarations against 11 rules and tells you exactly which ones are stale, broken, misplaced, or failing to take effect on disk. Two rules (PD001 and PD002) also detect phantom dependency imports - packages your source code imports that are not declared as a dependency.
Running the audit
# Scan current directory
cve-lite . overrides
# Scan a specific project
cve-lite /path/to/project overrides
# JSON output for CI
cve-lite . overrides --json
# Include network checks (required for OA007)
cve-lite . overrides --check-network
# Auto-fix all fixable findings
cve-lite . overrides --fix
# Fix a specific rule
cve-lite . overrides --fix --rule OA001
Use --check-overrides to run the full CVE scan and override hygiene together in one pass. It does not support --fix, --rule, or --check-network - use the overrides subcommand for those.
cve-lite . --check-overrides # CVE scan + hygiene in one pass
cve-lite . --check-overrides --json # combined JSON output
The overrides subcommand skips the CVE scan entirely - hygiene only, faster, and fully offline-capable:
cve-lite . overrides # hygiene only
cve-lite . overrides --fix # hygiene only, auto-fix where possible
The 11 rules
| Rule | Name | Severity | Auto-fix | What it detects |
|---|---|---|---|---|
| OA001 | Orphaned target | high | yes | Override target not present anywhere in the resolved tree |
| OA002 | Floating tag | medium | yes | Override pinned to "latest", "next", "*", or invalid semver |
| OA003 | Wrong section | high | yes | Override in the wrong package manager key - silently ignored at install time |
| OA004 | Surpassed pin | low | yes | Installed version already higher than the concrete pin |
| OA005 | Nested ineffective | low to critical | partial | Nested override that is silently ignored or cannot apply |
| OA006 | Coupled platform binary | high / medium | proposed | Override fights an exact-pinned parent - resolution is unpredictable |
| OA007 | Frozen latest | low | yes | Floating tag locked behind a newer registry version (requires --check-network) |
| OA008 | Materialized vulnerable copy | critical | no | Vulnerable package copy still on disk despite an active override floor |
| OA009 | Stale floor | low | yes | Override range floor already met by all parent declarations - safe to remove |
| PD001 | Override-only phantom | high | no | Package imported in source but only present via an override pin - not declared as a dependency |
| PD002 | Transitive-only phantom | medium | no | Package imported in source but only present as a transitive dependency - not declared explicitly |
How override debt accumulates
Auto-fix
Most findings can be fixed automatically. --fix applies RFC 6902 JSON patches to package.json atomically, preserving your existing formatting.
| Rule | Fixable? | What the patch does |
|---|---|---|
| OA001 | yes | remove the orphaned entry |
| OA002 | yes (when installed) | replace floating tag with >=<installed-version> |
| OA003 | yes | move override to the correct section |
| OA004 | yes (same major) | remove the surpassed pin |
| OA005.a/b/c | yes | remove the ineffective entry |
| OA005.d/e | suggest only | flattening requires manual review |
| OA006 | proposed | suggest parent dependency floor (not auto-applied) |
| OA007 | yes (with --check-network) | replace with >=<registry-latest> |
| OA008 | suggest only | investigate the parent dependency chain |
| OA009 | yes | remove the stale floor override |
| PD001 | no | declare the package as a dependency (npm install <pkg>) |
| PD002 | no | declare the package as a dependency (npm install <pkg>) |
CI integration
# Fail CI on any critical or high finding
cve-lite . --check-overrides --fail-on high
# Run as part of the regular CVE scan
cve-lite . --check-overrides --fail-on high
Log every detection and fix event for compliance audit trails:
cve-lite overrides . --fix --audit-log ./override-audit.ndjson
How this compares to other tools
Most dependency security tools read package.json statically and stop there. They see the override entry and assume it is working.
cve-lite . --check-overrides cross-checks overrides against the resolved lockfile and the installed node_modules tree - which is the only way to catch OA001 (orphaned), OA003 (wrong section), OA008 (still on disk despite floor), and OA006 (parent-coupling failure).
| Capability | --check-overrides | npm audit | OSV-Scanner | Snyk CLI | Socket CLI |
|---|---|---|---|---|---|
| Detect orphaned overrides (OA001) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Detect wrong-section overrides (OA003) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Detect overrides that fail on disk (OA008) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Detect stale range floors (OA009) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Cross-reference override against parent deps | ✅ | ❌ | ❌ | ❌ | ❌ |
| Auto-fix with RFC 6902 patches | ✅ | ❌ | ❌ | ❌ | ❌ |
| Works offline | ✅ | ❌ | ✅ | ❌ | ❌ |