When a CVE drops in a package you ship, the response sequence is fixed: confirm you actually ship an affected version, judge real exploitability, patch or mitigate, verify the fix reached production, and tell your customers what you found — in that order, and the first step should take minutes, not days. Teams that struggle with CVE response are almost never slow at patching. They are slow at answering the first question: do we even ship this? Everything below is organized around making each step fast.
First 30 minutes: confirm you actually ship it
If you maintain SBOMs per release, this is a query, not an investigation:
# Which of our images contain the affected component?
grype sbom:./release-4.2.1.cdx.json --only-fixed=false | grep CVE-2026-XXXXX
# Or straight against lockfiles if you have no SBOM discipline yet
grep -rn '"lodash"' services/*/package-lock.json
osv-scanner --lockfile services/api/package-lock.json
Three details bite people at this stage. First, check the version ranges in the advisory carefully — "affected: 4.17.0 through 4.17.20" means your 4.17.21 pin is fine and you can stand down. Second, check for the package under different names across ecosystems (the Java rebundle, the vendored copy, the static binary). Third, check all deployment surfaces: the product, the CLI you distribute, the demo environment with customer data that everyone forgot.
This is the step where an SBOM platform pays for itself. Answering "where do we ship xz across 300 services" from centralized SBOM inventory takes about a minute; answering it by grepping repos takes an afternoon during xz-utils-style news cycles, and afternoons are what you do not have.
Judge exploitability, not just severity
CVSS tells you how bad exploitation would be, not how likely it is. Before you page anyone, collect four data points:
| Signal | Where | What it changes |
|---|---|---|
| CISA KEV listing | kev.cisa.gov | Exploitation confirmed in the wild — treat as an incident |
| EPSS score | api.first.org | Probability of exploitation in 30 days; 0.1 and up deserves urgency |
| Reachability | Your SCA / call-graph analysis | Is the vulnerable function in any executed path |
| Exposure | Your architecture | Internet-facing request path vs. build-time-only tool |
A 9.8 in a package that only runs in an internal batch job behind VPN is a scheduled fix. A 7.5 deserialization bug in your public API's request path with an EPSS of 0.4 is tonight's work. The KEV catalog's growth has made this triage more tractable — it is the closest thing to ground truth on "attackers actually use this."
Patch, pin, or mitigate
The order of preference:
- Upgrade to the fixed release. Boring and correct. Check the changelog for breaking changes between your version and the fix.
- Force the transitive version when the fix is buried three levels down and your direct dependency has not updated yet:
overridesinpackage.json,constraintsfiles for pip,dependencyManagementin Maven. This is a loan, not a payment — file the follow-up to remove the override when upstream catches up. - Mitigate without patching when no fix exists: disable the affected feature flag, filter the exploit pattern at the WAF, drop the vulnerable endpoint from the router. Log4Shell taught everyone this tier —
log4j2.formatMsgNoLookups=trueshipped hours before most orgs could rebuild everything.
Whatever you choose, put it in one PR per affected repo with the CVE ID in the commit message. Your future auditor — and your future self, reconstructing the timeline — will thank you.
Verify the fix actually shipped
The most common CVE-response failure is declaring victory at merge. Merged is not deployed. Close the loop with evidence:
# Rebuild the SBOM from the deployed artifact and re-scan
syft registry.example.com/api:4.2.2 -o cyclonedx-json > post-fix.cdx.json
grype sbom:./post-fix.cdx.json | grep CVE-2026-XXXXX && echo "STILL PRESENT"
Run the check against what production is actually running (the digest in the cluster, not the tag in the pipeline). If you have exploit details, add a regression test or a WAF-side probe. Only then update the ticket.
Communicate: VEX and the audit trail
For every "we ship it but it does not affect us" conclusion, publish a VEX statement — not_affected with a machine-readable justification like vulnerable_code_not_in_execute_path — alongside your SBOMs. This is what stops fifty enterprise customers from filing fifty identical security questionnaires the same week. For the cases that did affect you, a short advisory with affected versions, fixed versions, and mitigation steps beats silence every time; customers remember vendors who told them before they asked.
Internally, record timestamps: advisory published, exposure confirmed, fix merged, fix deployed, customers notified. That timeline is your MTTR data, your SOC 2 evidence, and the input to the only retrospective question that matters — which step was slow?
Frequently asked questions
What if there is no fixed version yet?
Mitigate and monitor: reduce exposure (feature flags, network policy, WAF rules), subscribe to the advisory for updates, and record the decision with an expiry date. "No fix available" is a valid state, but it must be a tracked state, not a shrug.
Do I need to respond to every CVE within 24 hours?
No — and pretending you will guarantees you respond to none of them well. Reserve incident-speed response for KEV-listed or high-EPSS findings in exposed paths. Everything else goes through normal sprint-cadence remediation with SLAs by severity.
How do I handle a CVE in a package we vendored or forked?
You own it now: advisory feeds track the upstream name, so map your fork to the upstream CVE stream explicitly and backport the patch yourself. This maintenance tax is the strongest argument against vendoring in the first place.
What is the fastest way to know if the vulnerable code is reachable?
Reachability analysis in a modern SCA tool — Safeguard's SCA does call-graph checks against the advisory's affected symbols. Manual confirmation (grep for the API, trace the call site) works for one CVE, but not for the forty you will triage this quarter.