Safeguard
Security Guides•

Bump, pin, override, replace, fork or remove: which fix to use?

Six ways to fix a vulnerable dependency in plain words, with a decision table: bump, pin, override, replace, fork and remove, and when each applies.

Safeguard Security Team
5 min read

Start with the cheapest move that actually removes the vulnerable version. Bump if a fix exists in range, override if a parent blocks it, replace or fork if the library is abandoned, and remove if nothing needs it. Pinning alone holds a version steady but does not fix anything.

The six moves, defined

  • Bump: raise the version of a package you declare, or of the parent that brings it in, to a release that contains the fix.
  • Pin: fix a package at an exact version so it cannot drift. A pin can lock in a fixed version or, by mistake, freeze a vulnerable one.
  • Override: tell your package manager to use a specific version of a package wherever it appears in the tree, regardless of what parents request. The npm documentation describes overrides as a way to replace a version with a known security issue, or replace a dependency with a fork.
  • Replace: swap the library for a different one, usually with a code change.
  • Fork: take a copy of the source, fix it yourself, and depend on your copy.
  • Remove: delete the dependency and the code that used it.

Decision table

SituationFirst moveWhy
Fixed release exists and your range allows itBumpCheapest, reviewed by upstream
Fixed release exists but a parent caps the rangeBump the parent, else overrideKeeps the tree consistent
Fixed release is a new major versionBump with a migration planNeeds code changes and tests
No fix, change is smallPatch file, then pursue upstreamShort term stopgap
Project is abandoned, API is simpleReplaceStops carrying unpatched code
Project is abandoned, you need it exactlyForkYou own the maintenance
Nothing in your code uses itRemoveSmallest attack surface
Fixed version is known good and you want stabilityPin the fixed versionPrevents drift after the fix

Cost and risk, in short

MoveEffortOngoing dutyMain risk
BumpLow to mediumNoneBreaking change
PinLowRevisit laterFreezing a vulnerable version
OverrideLowRemove when parents catch upUntested combination
ReplaceMedium to highNone once doneBehavior differences
ForkHighYou patch it foreverFalling behind upstream
RemoveLow if unusedNoneHidden usage

Pinning is the one people confuse with fixing. A lock file pins everything already. What changes the outcome is which version the pin points at.

A sequence that works

  1. Confirm the finding is real for your build: is the package in the shipped artifact, and is the vulnerable code reachable.
  2. Check whether anything uses the dependency at all. If not, remove it.
  3. Look for a fixed version your ranges allow. If yes, bump.
  4. If a parent blocks it, upgrade the parent. If the parent has no newer release, use an override, and write down why and when to remove it.
  5. If no fix exists anywhere, decide between a patch, a replacement and a fork, and note the choice in the exception register with a review date.
  6. After the change, test (see the guide on what counts as a breaking change in a fix PR), rescan, and record the result.

Each ecosystem names these moves differently. The guides on overrides, constraints, patch sections and exclusions linked from this blog cover the syntax. This post is the decision layer above them.

Try it yourself

Click through it at your own pace, or open it full screen. Pick a finding and decide which of the six moves applies before you read the suggested action.

Where Safeguard fits

Safeguard scans dependencies, runs reachability analysis to show which findings your code can actually reach, and can open fix pull requests through autonomous remediation. That last feature is off by default and every category starts on Manual, so a person approves each change. You can try a free scan on a repository first.

Quick check

Is pinning a fix?

Only if the pin points at a fixed version. A pin on a vulnerable version just keeps it.

When is a fork better than a replacement?

When you need the library's exact behavior and its API is too large to migrate, and you accept maintaining it.

Which move is cheapest when the library is unused?

Removing it. It also shrinks the attack surface without any compatibility risk.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.