# How the osv-scanner fix Command Automates Vulnerability Patching for npm and Maven

> Automate npm and Maven vulnerability patching with osv-scanner fix. Discover how it builds dependency graphs, finds vulns, and applies patches for secure code.

- Repository: [Google/osv-scanner](https://github.com/google/osv-scanner)
- Tags: how-to-guide
- Published: 2026-04-25

---

**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`](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/fix/command.go). When executed, the command constructs a `FixVulnsOptions` struct that encapsulates all user constraints and remediation preferences:

```go
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](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/fix/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:

```go
if cmd.Bool("interactive") {
    return guidedremediation.FixVulnsInteractive(opts, GlamourRenderer{})
}
res, err := guidedremediation.FixVulns(opts)

```

*Source: [command.go#L303-L307](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/fix/command.go#L303-L307)*

## Core Remediation Logic

The `guidedremediation.FixVulns` function (implemented in the osv-scalibr library) executes a four-phase pipeline:

1. **Dependency graph resolution**: Resolves the complete transitive dependency tree using either deps.dev or native registries (npm registry/Maven Central).
2. **Vulnerability matching**: Joins OSV vulnerability records against the graph, applying filters for severity, depth, dev dependencies, and explicit ignore lists.
3. **Patch generation**: Computes minimal version upgrades respecting the `--upgrade-config` constraints and selected strategy.
4. **Patch ranking**: Sorts patches by vulnerabilities fixed per dependency change, respecting `--apply-top` and `--no-introduce` flags 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`](https://github.com/google/osv-scanner/blob/main/package-lock.json) directly without touching [`package.json`](https://github.com/google/osv-scanner/blob/main/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`](https://github.com/google/osv-scanner/blob/main/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`](https://github.com/google/osv-scanner/blob/main/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.json`](https://github.com/google/osv-scanner/blob/main/package-lock.json) directly without invoking npm.
- **npm relax**: Updates [`package.json`](https://github.com/google/osv-scanner/blob/main/package.json), deletes [`package-lock.json`](https://github.com/google/osv-scanner/blob/main/package-lock.json), spawns `npm install --package-lock-only`, and writes the new lockfile.
- **Maven override**: Modifies [`pom.xml`](https://github.com/google/osv-scanner/blob/main/pom.xml) to insert or update `<dependencyManagement>` sections.

Result formatting occurs in [`cmd/osv-scanner/fix/output.go`](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/fix/output.go), which reports:
- The number of vulnerabilities fixed
- Specific packages upgraded (`UPGRADED-PACKAGE` for npm, `OVERRIDE-PACKAGE` for Maven)
- Counts of remaining and unfixable vulnerabilities

*Source: [output.go#L22-L73](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/fix/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:

```bash
osv-scanner fix \
  --strategy=in-place \
  -L path/to/package-lock.json \
  --upgrade-config=minor

```

### Relax npm Constraints and Relock

Modify [`package.json`](https://github.com/google/osv-scanner/blob/main/package.json) constraints and regenerate the lockfile, applying only the top 5 most effective patches:

```bash
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:

```bash
osv-scanner fix \
  --strategy=override \
  -M path/to/pom.xml \
  --maven-registry=https://repo.mycompany.com/maven2 \
  --upgrade-config=major

```

## Summary

- The `osv-scanner fix` command orchestrates automated patching through [`cmd/osv-scanner/fix/command.go`](https://github.com/google/osv-scanner/blob/main/cmd/osv-scanner/fix/command.go) by building a `FixVulnsOptions` struct and invoking the `guidedremediation` library.
- **npm projects** support two strategies: **in-place** (lockfile editing) and **relax** (manifest modification with `npm install --package-lock-only` regeneration).
- **Maven projects** use the **override** strategy to inject `<dependencyManagement>` entries into [`pom.xml`](https://github.com/google/osv-scanner/blob/main/pom.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`](https://github.com/google/osv-scanner/blob/main/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`](https://github.com/google/osv-scanner/blob/main/package-lock.json) directly to upgrade vulnerable package versions while preserving existing [`package.json`](https://github.com/google/osv-scanner/blob/main/package.json) constraints, making it non-invasive to your manifest. The **relax** strategy modifies version constraints in [`package.json`](https://github.com/google/osv-scanner/blob/main/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`](https://github.com/google/osv-scanner/blob/main/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.