EPSS explained — when CVSS isn't enough
You have 800 CVE findings on your homelab and one evening to patch the urgent ones. CVSS gives you a severity score, but severity ≠ urgency. EPSS — the Exploit Prediction Scoring System — is the missing dimension: a 0–1 probability of actual exploitation in the next 30 days. Combined with CVSS, it cuts triage time by an order of magnitude.
The triage problem CVSS doesn't solve
CVSS scores answer "how bad is this if exploited?" — a structural question about the vulnerability's properties (network-attackable, no auth required, results in code execution). It says nothing about whether anyone is *likely* to exploit it.
That gap is enormous in practice. A typical Linux host has 40+ open CVEs at any given moment with CVSS ≥ 7.0; treating all of them as same-day patch priorities turns operators into patch-fatigued cynics who eventually ignore the dashboard. Most of those 40 CVEs will never be exploited against any target, ever. A handful will. Knowing which is the difference between "I patched the right thing tonight" and "I burned Saturday on something that didn't matter."
What EPSS is
The Exploit Prediction Scoring System is a model maintained by FIRST.org (the same body behind CVSS). For every published CVE, EPSS produces:
- An EPSS score from 0 to 1: the model's estimated probability that the CVE will be exploited in the wild in the next 30 days.
- An EPSS percentile from 0 to 100: where this CVE ranks against every other published CVE. A CVE with EPSS percentile 99 sits in the top 1% of "most likely to be exploited soon."
Scores are recomputed daily on the full CVE corpus. The model is an XGBoost ensemble trained on ~30 features per CVE, including:
- Whether public PoC code exists (GitHub, Exploit-DB, Metasploit modules).
- How long since the CVE was published.
- The CVSS vector breakdown (network attack vs local, auth required vs not).
- Vendor / product fingerprints (some products attract more attention).
- CWE classification (some bug classes are commoner exploitation targets).
- Whether the CVE is in CISA's Known Exploited Vulnerabilities catalogue.
The model is public and the EPSS project page publishes the daily-recomputed scores as open data. Every major commercial vulnerability scanner pulls from the same source.
How to read an EPSS score
EPSS values are not evenly distributed — most CVEs have very low scores, and a long tail has high ones. Rough buckets:
| EPSS | Reading | Action |
|---|---|---|
| < 0.01 | ~95% of all CVEs land here. The model's prediction is "essentially nobody will exploit this within a month." | Patch in your normal cycle. Don't lose sleep. |
| 0.01 – 0.10 | Some attention from public researchers; PoCs may exist; not yet seen in the wild. | Worth a same-week patch on internet-facing services. Backlog-worthy on internal-only. |
| 0.10 – 0.50 | Active interest. PoCs almost certainly exist; mass-scanner inclusion may be days away. | Same-day on internet-facing. Same-week on internal. |
| > 0.50 | Very likely to be exploited soon if not already. Combined with KEV inclusion, this means right now. | Patch tonight on internet-facing. Patch this week on internal. |
A heuristic: a CVE with EPSS > 0.10 deserves attention regardless of its CVSS. The model is saying "this thing is moving" — high CVSS or low, that's a reason to look.
The big counter-intuitive case: high CVSS, low EPSS
Most CVEs in your scan results will have CVSS 7.0+ (the bulk of "high" and "critical" buckets) but EPSS < 0.05. That pattern is the model saying: "yes, this would be bad if exploited, but it almost certainly won't be exploited in the next month." Reasons that's a true signal:
- The vulnerability requires a niche configuration most deployments don't have.
- The targeting cost (developing a working exploit, finding vulnerable hosts) is too high for the pay-off.
- The product is obscure enough that no exploit researcher has bothered.
- Public PoC code doesn't exist; an attacker would need to develop their own — most don't.
A CVSS 9.8 with EPSS 0.001 is an order of magnitude less urgent than a CVSS 7.5 with EPSS 0.40. The triage decision tree should reflect that.
EPSS vs KEV — they answer different questions
CISA's Known Exploited Vulnerabilities (KEV) catalogue is a curated list of CVEs that have *confirmed* exploitation in the wild. EPSS is a *predictive* model — "likely to be exploited" — versus KEV's *confirmed* observation — "we have receipts."
The two complement each other:
- EPSS leads KEV: high-EPSS CVEs that aren't yet in KEV are the "leading indicator" — patch before they graduate to confirmed-exploitation.
- KEV is ground truth: anything in KEV is urgent, regardless of CVSS or EPSS. CISA doesn't put speculative bugs in there; KEV inclusion means a real attack happened.
- The triage hierarchy: KEV-listed → patch tonight; EPSS > 0.5 → patch this week; EPSS 0.1–0.5 → patch in cycle, prioritised by exposure; EPSS < 0.1 → normal cadence.
Both signals are public data; both should appear on every CVE finding in a serious vulnerability scanner.
Where EPSS falls short
Three known limitations worth knowing about:
Lagging indicator on novel attack patterns
EPSS learns from past exploitation patterns. Genuinely novel attack types — a new CWE class, a new privilege escalation gadget — will score low until enough public signal accumulates. The model is a rear-view mirror with predictive smoothing, not a crystal ball.
Targeted attacks don't show up
EPSS scores reflect *mass* exploitation patterns. A nation-state actor sitting on a 0-day for six months while attacking three specific organisations will not move the EPSS score on that CVE — until the 0-day is publicly disclosed and mass scanners start using it. If your homelab is in someone's specific crosshairs (unlikely, but possible — journalists, activists, researchers, founders of payment-processing companies), EPSS is not the right signal to triage by.
Your environment isn't the average
EPSS scores reflect what attackers do globally. Your *exposure* to a given CVE depends on your environment — is that vulnerable service internet-facing, behind a VPN, or LAN-only? A CVE with EPSS 0.6 on a service you don't expose is less urgent than one with EPSS 0.3 on your edge proxy. Use EPSS as one input, not the whole answer.
A worked example
A scan finds three CVEs on your homelab edge box:
| CVE | CVSS v3 | EPSS | KEV? | Service |
|---|---|---|---|---|
| CVE-A | 9.8 | 0.002 | No | An internal-only metrics dashboard |
| CVE-B | 7.5 | 0.42 | No | Your reverse proxy (public) |
| CVE-C | 8.1 | 0.94 | Yes | SSH (public) |
The naive CVSS-only ordering: A (9.8) → C (8.1) → B (7.5).
The EPSS-aware ordering: C (KEV + 0.94 + public) tonight; B (0.42 + public) this week; A (0.002 + internal-only) next cycle. The 9.8 CVSS that scared the audit software is the lowest urgency of the three; the 8.1 that sits below it on a CVSS-only list is the actually urgent one.
That re-ordering is *the* triage win EPSS gives you. It's not a replacement for CVSS; it's the second axis that makes a flat severity list into a real action plan.
How Noxen surfaces EPSS
Every CVE finding in Noxen carries the upstream EPSS score and KEV-listed flag when the upstream feed includes them. Findings > 0.10 EPSS show as a yellow tag on the row; KEV-listed findings show as a green "KEV" badge regardless of CVSS. The dashboard's default sort is severity-first; toggle to EPSS-weighted to see findings ordered by the "how likely is this actually exploited" axis described above.
The severity-scoring docs cover the precedence rules (distro-tagged severity → CVSS v3 → database fallback) — KEV/EPSS overlay tags on top of those buckets, they don't replace them. Noxen never re-scores upstream data; the EPSS values you see come straight from FIRST.org's daily publication via the signed CVE feed.
The TL;DR
- CVSS = "how bad if exploited." EPSS = "how likely to be exploited soon." You need both.
- Use EPSS > 0.10 as a "this deserves attention" trigger regardless of CVSS bucket.
- Combine KEV (confirmed exploited) + EPSS (likely soon) as a two-signal urgency tier above the regular CVSS bucket ordering.
- EPSS reflects mass exploitation; it doesn't predict targeted attacks. Don't rely on it for high-target environments.
- Your *exposure* (internet-facing vs LAN-only) is the third axis. Low-EPSS-on-public can outrank high-EPSS-on-internal.