Software Securityhome
Fix a findingSearch
Phase 6 · Maintenance

Dependency patching

Dependency patching is the routine work of keeping the open-source and third-party components you ship free of known vulnerabilities: confirming that each advisory applies to what you actually ship, upgrading to a fixed version, and recording the reason when you do not.

Every advisory for a component you ship tells attackers where to look, and most findings arrive through packages you never chose directly: in a measured Node.js example on this site, 11 of 16 came from express 4.19.2 and the packages it pulls in. Without a routine, teams chase every alert or ignore them all; with one, a single parent upgrade often closes many findings at once.

Who
The team that owns the service, with update bots doing routine bumps and AppSec settling disputed or exploited cases
When
When a scanner or update bot reports a new advisory, and before each release
How often
Update pull requests reviewed weekly; due dates from the prioritization policy; exploited cases at once
You end up with
Upgraded lockfiles and rebuilt artifacts, and a record per finding: fixed, not affected with evidence, or accepted with an expiry

Do this

  1. Scan what you ship and automate updates

    Scan lockfiles on every pull request, and built images on a schedule, with a tool such as OSV-Scanner, Dependabot or another software composition analysis tool. Turn on automated security updates: Dependabot, for example, opens a pull request to the minimum version that includes the patch. Look up a single package with OSV dependency lookup.

  2. Collapse duplicates and confirm the copy ships

    One vulnerability can arrive as GHSA, PYSEC and CVE records; keep one finding per alias group, package, version and artifact. Confirm the copy reaches the shipped artifact with npm ls <package> --omit=dev or the image SBOM. Match ecosystem and package name exactly, and for operating system packages use the distribution's advisory, because a backported fix keeps the old version number.

  3. Check the advisory's precondition

    Most advisories say what must be true for the bug to matter, such as a route shape, attacker-controlled templates or user input in a cookie name. Check it with something you can rerun: a code search, a test, or a call-graph tool such as govulncheck, which separates Go vulnerabilities your code calls from those it only imports. Record the scope of the check and what would reopen it.

  4. Upgrade the parent first, then rescan

    Most transitive findings close when their parent moves, so upgrade direct dependencies before analyzing each child; the OWASP Vulnerable Dependency Management Cheat Sheet also advises acting on the direct dependency. Rescan the new lockfile before merging, because an upgrade can add findings. If the parent's range cannot reach the fix, use an overrides or resolutions entry with tests, or record a dated exception.

  5. Test, rebuild and verify what runs

    Run the test suite against the upgraded dependency, then rebuild without a cached dependency layer and deploy. Close the finding only when a rescan of the built image or its SBOM shows the fixed version and every environment, including workers and scheduled jobs, runs that digest. A merged pull request is an intermediate step, not the fix.

  6. Record one outcome per finding

    Give each finding exactly one outcome and an owner: fixed by its due date (Risk-based prioritization), not affected with a VEX not_affected statement and its justification, accepted with an expiry and a compensating control, or escalated. Keep the original detection beside the decision, so a later scan of the same package can be matched to it.

  7. Handle no-fix and exploited cases on purpose

    With no fixed version yet, apply the maintainer's workaround or isolate the affected feature, and track it with an expiry. Make a plan for each unmaintained package, such as replacing it, as SSDF task PW.4.4 suggests. If the finding is in CISA's KEV catalog or credibly exploited and you run it, stop triaging and respond as an incident (Respond to an exploited or malicious dependency).

Done when

Each dependency finding has a recorded decision with evidence, and known-exploited ones are fixed first.

Mark it in the gap check

Common mistakes

  • Closing on a merged pull request. A cached build layer or a rarely deployed worker can keep shipping the old version, so close on the deployed digest.
  • Treating development-only copies as production findings, or production copies as development-only without checking. Both waste time or hide real exposure.
  • Pinning the first fixed release and moving on. Eight days after the React2Shell fix, React disclosed three more vulnerabilities in the same code, so recheck the advisory until the case closes.
  • Recording "not reachable" without its scope. A negative result covers only the code and entry points examined, and it expires when either changes.
  • Suppressing a scanner rule or a whole package to quiet the noise. Suppress one vulnerability ID for one package, with a reason and an expiry.

Which outcome does a finding get?

Route each finding to exactly one row. The due date for a fix comes from your prioritization policy, not from this table.

Which outcome does a finding get?: table
OutcomeUse it whenRecord
IncidentExploited (KEV or credible reports) and present in a deployed artifactAn incident ticket with the affected digests
Fix by due dateShipped, and the precondition holds or cannot be ruled outDue date, owner and the planned upgrade
Fix on the normal cadenceShipped, precondition absent, fix availableVEX not_affected with a justification and a reopen trigger
Not affectedNot in any shipped artifact, such as a development-only copyScope evidence, such as npm ls --omit=dev output
Not a matchWrong ecosystem or package, or a distribution backport already fixed itThe mismatch and any distribution advisory
Accepted riskShipped, with no fix or no compatible fix yetOwner, expiry date and compensating control

Tools and guides

Standards

NIST SSDF 1.1
PW.4 Reuse Existing, Well-Secured Software When Feasible Instead of Duplicating FunctionalityRV.2 Assess, Prioritize, and Remediate Vulnerabilities

Sources

  1. OWASP Vulnerable Dependency Management Cheat Sheet
  2. OSV-Scanner: usage
  3. GitHub Docs: About Dependabot security updates
  4. Go: Tutorial: Find and fix vulnerable dependencies with govulncheck
  5. npm Docs: npm ls. npm v11.
  6. OpenVEX specification. v0.2.0.
  7. React: Denial of Service and Source Code Exposure in React Server Components. 11 December 2025, updated 26 January 2026.
  8. NIST SP 800-218: Secure Software Development Framework (SSDF) Version 1.1 (PW.4.4, RV.2). February 2022.
  9. OWASP SAMM: Secure Build, Software Dependencies stream
  10. OWASP SAMM: Environment Management, Patching and Updating stream

Find your next answer

Type to search. Search runs in your browser.

Searches run in your browser, but the host can infer them from the index files they load. The address shows your search so you can bookmark or share it.