Supply Chain · Jul 25, 2026 · 7 min read

End-of-life dependency risk: the CVEs that will never be patched

When a dependency reaches end-of-life, the patches stop but the CVEs keep coming. Reachability and KEV membership decide whether that accumulating backlog is noise or a same-week action.

When a dependency reaches end-of-life, the CVEs do not stop accumulating - the patches do. The last version is a fixed snapshot of vulnerabilities discovered up to that moment, plus every vulnerability discovered afterward that nobody will ever fix. CVSS scores keep arriving. Remediation never does.

01What EOL actually means for your attack surface

Active maintenance means someone receives a CVE report, evaluates it, and ships a patch. EOL means that chain is broken. The code is identical to the last supported release; the attack surface is identical; the only thing that changed is that no one will act on what researchers find next.

The risk compounds in two directions. New CVEs filed against the EOL component accumulate without a patch target - every scanner that reports them is correct, but the remediation path is version replacement, not a point upgrade. Meanwhile, old CVEs that were fixed in the supported branch but never backported remain open permanently. The version pinned in your lockfile is the high-water mark of what was patched before the project closed.

Maintained dependency CVE filed ──► vendor triages ──► patch released ──► upgrade available EOL dependency CVE filed ──► NVD records it ──► no patch ever ──► backlog grows EPSS score rises as PoC matures
An EOL component sits in the CVE feed forever without a remediation path. EPSS probability rises as exploit code matures but there is nothing to upgrade to.

The practical effect is that your SLA clock never stops. A CVE filed eighteen months after EOL still triggers a 7-day critical SLA in most policies. Your team will triage it, confirm no patch exists, and close it as accepted risk - every time, for every new CVE, until the component is replaced. That triage overhead is the hidden cost of deferring the replacement.

02Reachability separates noise from a real exposure

Not every EOL component is a high-priority replacement. The deciding question is whether the vulnerable code path is actually reachable from the application's entry points. An EOL library pulled in as a transitive dependency of a build tool that never ships to production is a compliance note. An EOL HTTP client sitting on the request path of your payments API is a 7-day action item.

Call-graph reachability resolves this without guesswork. The SCA engine traces import chains from entry points to the component, then from the component to the functions flagged in the CVE. A CVE that describes a parsing flaw in a function no call path ever reaches is rated differently from one where the sink is reachable from an authenticated endpoint. That distinction collapses the backlog before any human triages it.

sbom-fragment.jsonjson
// SCA finding for an EOL component with reachability annotation
{
  "component": "com.example:legacy-xml-parser:2.4.1",
  "eol_date": "2023-06-30",
  "cves": [
    {
      "id": "CVE-2024-38201",
      "cvss": 9.1,
      "epss": 0.72,
      "kev": true,
      "reachable": true,
      "call_path": "PaymentsController.parse -> XmlParser.readExternal"
    },
    {
      "id": "CVE-2025-11042",
      "cvss": 7.5,
      "epss": 0.09,
      "kev": false,
      "reachable": false,
      "call_path": "null (no call path from entry points)"
    }
  ]
}

The first CVE is on KEV with a reachable call path to the payments controller - it gets a 7-day SLA regardless of EOL status. The second is unreachable; it becomes a tracked backlog item that closes when the component is eventually replaced, not an emergency that pulls the on-call engineer at midnight.

03EOL detection is a data problem, not a CVE problem

CVE databases track vulnerability identifiers, not maintenance status. A component can be EOL for two years with no new CVEs filed and a vulnerability scanner will report it clean - because it is comparing against an identifier list, not against a support lifecycle database. The two signals are orthogonal and both are necessary.

Lifecycle data comes from sources separate from the NVD feed: endoflife.date publishes structured EOL dates for hundreds of runtimes, frameworks and libraries. Package registries sometimes publish deprecation notices. Some ecosystems have formal long-term-support designations with public end dates. Correlating the installed version against these sources is a distinct check from CVE correlation, and omitting it produces a scanner that sees a clean bill of health on a component with a three-year-old EOL date.

SignalSourceWhat it tells you
CVE / CVSSNVD, OSV, vendor advisoriesKnown vulnerabilities with severity at time of filing
EPSSFIRST EPSS model (daily)Exploitation probability in the next 30 days
KEVCISA KEV catalogCertified active exploitation by a threat actor
EOL dateendoflife.date, registry metadataWhether a patch will ever exist for future CVEs
ReachabilityCall-graph analysis at scan timeWhether the vulnerable code path is reachable in your application

The posture view merges all five. A component that is reachable, KEV-listed, and EOL is the worst combination: exploitation is confirmed in the wild, a patch does not exist, and the code is on a live call path. That finding sits at the top of the queue regardless of how old the EOL date is.

Proven - CriticalEOL component with KEV CVE - reachable call path - PaymentsController
Component: com.example:legacy-xml-parser:2.4.1 (EOL: 2023-06-30) CVE: CVE-2024-38201 CVSS 9.1 EPSS 0.72 KEV: yes Call path: PaymentsController.parse ──► XmlParser.readExternal (reachable from authenticated endpoint) Patch available: no - component is EOL. Replacement required.
Oracle: SBOM + call-graph. No patch path exists; remediation is dependency replacement, not upgrade. SLA: 7 days (critical, KEV, reachable).

04The remediation is replacement, not a patch bump

Most SCA findings close with a version upgrade. EOL findings do not. The remediation path is identifying a maintained alternative, porting the integration, and verifying the replacement under the same scan that flagged the original. Until that work is complete, the finding stays open with a tracked accepted-risk note and a scheduled review date.

Two failure modes to avoid. The first is treating EOL as purely a compliance flag and accepting risk indefinitely without a replacement plan - accepted risk is a state, not a resolution. The second is suppressing the finding entirely because no patch exists, which removes it from the posture view and the SLA clock without actually reducing the exposure. A finding with no patch should be visible and scheduled, not silent.

0
patches available for an EOL CVE
5
signals merged per finding (CVE, EPSS, KEV, EOL, reachability)
7d
SLA when KEV + reachable, regardless of patch availability

An EOL component is not a lower-priority finding because the vendor stopped caring. It is a higher-priority one, because the only path to a green posture is a replacement - and the longer that work is deferred, the more CVEs accumulate in a queue that has no merge target.

Evidence over heuristicsReachable beats foundMonitor → Block: rolling out a gate without slowing teamsIaC-grounded threat modelingAir-gapped AppSec with no phone-homeOne platform vs three tools
See it on your own app →