Skip to main content

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

RuleNameSeverityAuto-fixWhat it detects
OA001Orphaned targethighyesOverride target not present anywhere in the resolved tree
OA002Floating tagmediumyesOverride pinned to "latest", "next", "*", or invalid semver
OA003Wrong sectionhighyesOverride in the wrong package manager key - silently ignored at install time
OA004Surpassed pinlowyesInstalled version already higher than the concrete pin
OA005Nested ineffectivelow to criticalpartialNested override that is silently ignored or cannot apply
OA006Coupled platform binaryhigh / mediumproposedOverride fights an exact-pinned parent - resolution is unpredictable
OA007Frozen latestlowyesFloating tag locked behind a newer registry version (requires --check-network)
OA008Materialized vulnerable copycriticalnoVulnerable package copy still on disk despite an active override floor
OA009Stale floorlowyesOverride range floor already met by all parent declarations - safe to remove
PD001Override-only phantomhighnoPackage imported in source but only present via an override pin - not declared as a dependency
PD002Transitive-only phantommediumnoPackage 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.

RuleFixable?What the patch does
OA001yesremove the orphaned entry
OA002yes (when installed)replace floating tag with >=<installed-version>
OA003yesmove override to the correct section
OA004yes (same major)remove the surpassed pin
OA005.a/b/cyesremove the ineffective entry
OA005.d/esuggest onlyflattening requires manual review
OA006proposedsuggest parent dependency floor (not auto-applied)
OA007yes (with --check-network)replace with >=<registry-latest>
OA008suggest onlyinvestigate the parent dependency chain
OA009yesremove the stale floor override
PD001nodeclare the package as a dependency (npm install <pkg>)
PD002nodeclare 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-overridesnpm auditOSV-ScannerSnyk CLISocket 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