How the osv-scanner fix Command Automates Vulnerability Patching for npm and Maven
The osv-scanner fix command automates vulnerability patching by building a full dependency graph, querying OSV for vulnerable packages, computing minimal upgrade patches, and applying them via ecosystem-specific strategies—in-place lockfile edits for npm and dependencyManagement overrides for Maven.
The osv-scanner fix command provides guided remediation capabilities for Node.js and Java projects within the google/osv-scanner repository. This tool integrates with the OSV database and deps.dev ecosystem to resolve vulnerable dependencies without manual version hunting. Understanding how the osv-scanner fix command automates vulnerability patching for npm and Maven helps teams integrate automated security fixes into their CI/CD pipelines.
CLI Entry Point and Configuration
The entry point for the fix command resides in cmd/osv-scanner/fix/command.go. When executed, the command constructs a FixVulnsOptions struct that encapsulates all user constraints and remediation preferences:
opts := options.FixVulnsOptions{
RemediationOptions: options.RemediationOptions{
ResolutionOptions: options.ResolutionOptions{
MavenManagement: cmd.Bool("maven-fix-management"),
},
IgnoreVulns: cmd.StringSlice("ignore-vulns"),
ExplicitVulns: cmd.StringSlice("vulns"),
DevDeps: !cmd.Bool("ignore-dev"),
MinSeverity: cmd.Float64("min-severity"),
MaxDepth: cmd.Int("max-depth"),
UpgradeConfig: upgrade.NewConfigFromStrings(cmd.StringSlice("upgrade-config")),
},
Manifest: cmd.String("manifest"),
Lockfile: cmd.String("lockfile"),
Strategy: strategy.Strategy(cmd.String("strategy")),
MaxUpgrades: cmd.Int("apply-top"),
NoIntroduce: cmd.Bool("no-introduce"),
}
Source: command.go#L220-L236
The command then initializes a resolution client (either deps.dev or native registry) and a Maven client when processing Java projects. It delegates the actual remediation work to the guidedremediation library:
if cmd.Bool("interactive") {
return guidedremediation.FixVulnsInteractive(opts, GlamourRenderer{})
}
res, err := guidedremediation.FixVulns(opts)
Source: command.go#L303-L307
Core Remediation Logic
The guidedremediation.FixVulns function (implemented in the osv-scalibr library) executes a four-phase pipeline:
- Dependency graph resolution: Resolves the complete transitive dependency tree using either deps.dev or native registries (npm registry/Maven Central).
- Vulnerability matching: Joins OSV vulnerability records against the graph, applying filters for severity, depth, dev dependencies, and explicit ignore lists.
- Patch generation: Computes minimal version upgrades respecting the
--upgrade-configconstraints and selected strategy. - Patch ranking: Sorts patches by vulnerabilities fixed per dependency change, respecting
--apply-topand--no-introduceflags to prevent introducing new vulnerabilities.
Remediation Strategies Explained
The strategy flag determines how patches apply to project files. Each ecosystem supports specific strategies optimized for its dependency model.
npm In-Place Strategy
The in-place strategy modifies package-lock.json directly without touching package.json. It replaces vulnerable package versions with patched versions inside the existing lockfile structure. This approach preserves your current dependency tree while eliminating known vulnerabilities, making it ideal when you want minimal changes to tested configurations.
npm Relax Strategy
The relax strategy modifies version constraints in package.json, deletes the existing lockfile, and executes npm install --package-lock-only to regenerate a fresh dependency tree. According to the source analysis, this recomputes the entire dependency graph and allows npm's resolver to find compatible version combinations that may not be achievable through in-place edits. Use this when in-place fixes conflict with existing peer dependency constraints.
Maven Override Strategy
For Maven projects, the override strategy manipulates the pom.xml to force non-vulnerable versions. The tool adds or updates <dependencyManagement> entries (or direct <dependencies> when specified) to override transitive dependency versions. This leverages Maven's dependency mediation rules to force specific versions without modifying the original dependency declarations.
Patch Application and File Updates
After computing the optimal patch set, the system writes changes to disk:
- npm in-place: Rewrites
package-lock.jsondirectly without invoking npm. - npm relax: Updates
package.json, deletespackage-lock.json, spawnsnpm install --package-lock-only, and writes the new lockfile. - Maven override: Modifies
pom.xmlto insert or update<dependencyManagement>sections.
Result formatting occurs in cmd/osv-scanner/fix/output.go, which reports:
- The number of vulnerabilities fixed
- Specific packages upgraded (
UPGRADED-PACKAGEfor npm,OVERRIDE-PACKAGEfor Maven) - Counts of remaining and unfixable vulnerabilities
Source: output.go#L22-L73
Practical Usage Examples
Auto-fix npm Lockfile In-Place
Apply minor version bumps directly to the lockfile without touching manifest constraints:
osv-scanner fix \
--strategy=in-place \
-L path/to/package-lock.json \
--upgrade-config=minor
Relax npm Constraints and Relock
Modify package.json constraints and regenerate the lockfile, applying only the top 5 most effective patches:
osv-scanner fix \
--strategy=relax \
-M path/to/package.json \
-L path/to/package-lock.json \
--apply-top=5
Override Maven Transitive Dependencies
Add dependencyManagement entries to force secure versions using a custom corporate registry:
osv-scanner fix \
--strategy=override \
-M path/to/pom.xml \
--maven-registry=https://repo.mycompany.com/maven2 \
--upgrade-config=major
Summary
- The
osv-scanner fixcommand orchestrates automated patching throughcmd/osv-scanner/fix/command.goby building aFixVulnsOptionsstruct and invoking theguidedremediationlibrary. - npm projects support two strategies: in-place (lockfile editing) and relax (manifest modification with
npm install --package-lock-onlyregeneration). - Maven projects use the override strategy to inject
<dependencyManagement>entries intopom.xml. - The tool queries OSV.dev and package registries (deps.dev, npm registry, Maven Central) to compute minimal upgrades respecting flags like
--upgrade-config,--max-depth, and--min-severity. - Results are formatted in
cmd/osv-scanner/fix/output.go, reporting fixed vulnerabilities and upgrade counts in either human-readable text or JSON format.
Frequently Asked Questions
What is the difference between the in-place and relax strategies for npm?
The in-place strategy edits package-lock.json directly to upgrade vulnerable package versions while preserving existing package.json constraints, making it non-invasive to your manifest. The relax strategy modifies version constraints in package.json first, then deletes and regenerates the lockfile using npm install --package-lock-only, which allows npm's resolver to find compatible version combinations that strict lockfile editing cannot achieve.
How does osv-scanner fix handle Maven transitive dependencies?
For Maven, the tool uses the override strategy to add or update <dependencyManagement> entries in pom.xml. According to the implementation in google/osv-scanner, this forces specific non-vulnerable versions of transitive dependencies without requiring changes to direct <dependencies> declarations, leveraging Maven's dependency mediation to prioritize the managed versions.
Can I limit which vulnerabilities the fix command attempts to patch?
Yes. The command supports multiple filtering flags: --ignore-vulns to exclude specific vulnerability IDs, --vulns to target only specific IDs, --min-severity to set a severity threshold, and --max-depth to limit how deep in the dependency tree the tool searches. Additionally, --no-introduce prevents applying patches that would introduce new vulnerabilities.
Where does the vulnerability data and package metadata originate?
The osv-scanner fix command queries the OSV.dev API for vulnerability information and retrieves package metadata from either deps.dev or ecosystem-native registries depending on your configuration. For npm, it uses the npm registry; for Maven, it uses Maven Central or a custom registry specified via --maven-registry. This data feeds the guidedremediation library's graph resolution and patch computation algorithms.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →