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
CLI
# Append override hygiene to a regular CVE scan and fail on high or critical
cve-lite . --check-overrides --fail-on high
# Run a dedicated hygiene-only audit and fail on high or critical
cve-lite . overrides --fail-on high
Log every detection and fix event for compliance audit trails:
cve-lite . overrides --fix --audit-log ./override-audit.ndjson
GitHub Action
Override hygiene is available natively through the CVE Lite CLI Action - you configure it with first-class inputs, not raw flags. There are two modes.
Run it inline with the CVE scan:
- uses: OWASP/cve-lite-cli@v1
with:
check-overrides: 'true'
fail-on: 'high'
Or run a dedicated override audit as its own step, with its own severity gate:
- uses: OWASP/cve-lite-cli@v1
with:
overrides: 'true'
overrides-fail-on: 'high'
check-network: 'true' # enable the OA007 registry-drift check
audit-log: './override-audit.ndjson' # NDJSON change-control trail
| Action input | What it does |
|---|---|
check-overrides | Run override hygiene inline with the scan; findings appear in the same report |
overrides | Run a dedicated cve-lite overrides audit as a separate step |
overrides-fail-on | Exit non-zero when the dedicated audit finds an issue at or above this severity |
check-network | Allow the override audit to make registry calls for the OA007 drift check (off by default in CI) |
audit-log | Stream override detection and fix events as NDJSON for change-control |
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 | ✅ | ❌ | ✅ | ❌ | ❌ |
Related
Override hygiene answers did my manual patch work. Its sibling, Maintenance Risk Detection (--check-maintenance), answers why can't I fix this at all - flagging a direct dependency that blocks a transitive CVE fix behind a major-version upgrade, or that is deprecated on npm. Run both alongside a scan with cve-lite . --check-overrides --check-maintenance.