EPSS Is the Triage Signal Your CVSS Score Was Never Going To Be
1. CVSS does not say what triage assumes it says
CVSS v3.1 is a severity model. It quantifies the worst-case impact of a vulnerability assuming successful exploitation, scoped to a single instance, in a generic environment, by a competent attacker. The score is intentionally context-free. A 9.8-CVSS vulnerability is one that, if exploited, will deliver high confidentiality, integrity, and availability impact via a network vector with no authentication required.
The word "if" carries the entire weight of the sentence. CVSS says nothing about how likely the exploitation is. It says nothing about whether public exploit code exists, whether the bug is being scanned for in the wild, whether ransomware affiliates have adopted it, or whether the vendor's patch is widely adopted. Two CVEs with identical 9.8 CVSS scores can have a 1000x gap in their actual exploitation rate, and triage queues that sort by CVSS waste their highest-value attention on the wrong one.
This is not a new observation. The FIRST CVSS user guide has said it explicitly for years: CVSS is a severity score, not a risk score. Practitioners ignore the guidance because they have no alternative score that ranks the same CVEs by probability of exploitation. EPSS is that alternative.
2. What EPSS is and what it measures
EPSS, the Exploit Prediction Scoring System, is a probability model maintained by FIRST. The model ingests a CVE plus a feature vector (CVSS components, vendor, age, presence in CISA KEV, Twitter mentions, exploit-DB references, and dozens of others) and produces a daily-updated probability that the CVE will be exploited in the wild within the next 30 days.
A CVE with EPSS = 0.05 has a five percent probability of being exploited in the next thirty days. A CVE with EPSS = 0.93 has a ninety-three percent probability. The model is calibrated against historical exploitation data and published with a percentile rank so you can interpret the score relative to the rest of the active CVE corpus.
The EPSS model documentation is open. The model retrains daily. The scores are free, queryable via API, and update for every active CVE in the CVE programme.
EPSS solves the missing half of the triage equation. CVSS tells you how bad it would be. EPSS tells you how likely it is. The product (or, more usefully, a careful weighted sum) tells you where to spend the next analyst-hour.
3. How we weight EPSS in the projector
Our Version Vulnerability Projector ranks every projected CVE for every customer asset. The naive ranker uses CVSS alone. The current ranker uses four signals, weighted as follows:
def triage_score(p: CVEProjection) -> float:
cvss_term = p.cvss / 10.0 # 0.0–1.0
epss_term = p.epss # 0.0–1.0
kev_term = 1.0 if p.in_kev else 0.0 # binary
chain_term = 1.0 if p.starts_known_chain else 0.0 # binary
# The four weights add to 1.0; chosen by retrospective
# calibration against six months of customer remediation outcomes.
return (
0.20 * cvss_term
+ 0.45 * epss_term
+ 0.25 * kev_term
+ 0.10 * chain_term
)
EPSS gets 45 percent of the weight because it is the only term that updates daily against ground-truth exploitation signal. CVSS gets 20 percent because it is the only term that anchors the worst-case impact. KEV gets 25 percent because CISA's catalogue is the lower bound on observed exploitation, a CVE that appears on KEV is one that defenders should treat as currently weaponised. Chain membership gets 10 percent because a low-CVSS first node can unlock a critical end state, and the triage queue should surface those rather than burying them under direct-impact findings.
The weights are not magic. They are calibrated against a six-month rolling window of our own remediation outcomes: for which findings did the customer ship a patch within 14 days, for which did the customer accept the risk, and for which did exploitation activity actually appear in customer telemetry. The weights get re-tuned quarterly against the same window. We publish the weights to every customer so they can re-rank in their own scoring tool if their environment demands a different weighting (regulated industries usually push CVSS higher; cloud-native shops usually push chain higher).
4. Where the EPSS model breaks
Three failure modes are documented and operationally relevant.
Brand-new CVEs. EPSS needs feature data: and the feature set includes vendor advisories, public PoC links, social media activity, and exploit-DB references. A CVE published an hour ago has none of these signals, so its EPSS score sits near the corpus median (around 0.01-0.02) until the model has something to feed on. For brand-new high-CVSS CVEs, the projector down-weights EPSS for the first 72 hours and leans on CVSS plus the moat builder patch-diff signal (was the patch ship analysable, did it touch a security-relevant code path, is the diff being weaponised on GitHub right now?) until EPSS has signal.
Old CVEs that exploit-trends ignore. A 2018 vulnerability that nobody scans for in 2026 will have a low EPSS score. That score is correct on average (most attackers do not bother with old, niche CVEs) but it is wrong for the customer whose infrastructure still runs the vulnerable version. We override the EPSS-low / version-vulnerable case with a fixed floor: any inherited CVE with cvss >= 7.0 gets a triage-score minimum of 0.4 regardless of EPSS. The override prevents the long-tail CVEs from disappearing into the bottom of the queue.
Vendor-specific CVEs without telemetry. EPSS depends on observation. Closed enterprise software with a small install base will have a thin signal even when exploitation is happening, the data does not reach the model because nobody publishes it. For these vendors, we maintain a manual override list, updated weekly by our threat-intel team, that promotes specific CVEs into the high-triage bucket when our dark-web monitoring sees PoCs being traded or proof-of-life screenshots being posted. Manual overrides expire after 90 days unless EPSS picks up the signal independently.
5. The operational rule that keeps the queue actionable
The triage rule we recommend to every customer fits in a single sentence: patch every finding with EPSS over 0.5 within seven days, every finding in CISA KEV within fourteen days, every finding with CVSS over 9.0 within thirty days, and everything else within the next quarterly maintenance window.
The seven-day rule is the load-bearing one. Once a CVE crosses EPSS = 0.5, the model is saying it is more likely than not to be exploited within the month. Seven days is the operational tempo at which most customers' change-management windows can act without invoking an emergency-change process. Beyond seven days, the probability that the customer becomes a casualty climbs faster than the patch backlog clears.
The KEV rule covers the case where exploitation is already documented and ongoing. The CVSS rule covers the case where the bug is severe enough that even a low EPSS does not absolve the team, a 9.8 with EPSS 0.05 still warrants quarterly attention because the impact ceiling is catastrophic. The quarterly catch-all covers everything else.
A customer running this rule against our projector typically sees their open-finding count drop by an order of magnitude within the first quarter, because the queue is sorted by what actually warrants attention rather than by what scored highest in the lab.
6. The number you should look up tomorrow morning
Pull the EPSS API for the top ten CVEs that appear in your last scan report. Sort by EPSS descending. The top of the list is your real backlog. The bottom of the list is your tracking backlog: record it, monitor it, re-check it monthly, but do not let it consume your week.
The single largest improvement most teams can make to their vulnerability programme costs nothing, requires no new tooling, and is shipped by every modern scanner including ours. Re-rank the queue by exploitation probability, not severity. The number of incidents that follow will drop the next quarter.
Verifiable security.