If you’ve worked in vulnerability management for more than a few months, you’ve lived through the CVSS triage treadmill: scanner produces 300 “critical” findings, team works through 50 of them, the rest age indefinitely in a backlog, and a breach happens via a CVE that was rated 7.5 and deprioritized.
CVSS (Common Vulnerability Scoring System) is good at quantifying theoretical severity. It’s poor at answering the question that actually drives risk decisions: is this being exploited right now?
EPSS was built to answer that question.
What is EPSS?
EPSS — Exploit Prediction Scoring System — is a data-driven model developed by a working group under FIRST (Forum of Incident Response and Security Teams). It produces a probability score (0–1) representing the likelihood that a CVE will be exploited in the wild within the next 30 days.
The model is trained on:
- CVE characteristics (age, CVSS vector, vulnerability type, affected software)
- Real-world exploitation data from threat intelligence feeds, honeypots, and IDS telemetry
The result is updated daily and published at epss.cyentia.com.
CVSS vs EPSS: The Numbers Tell the Story
The Cyentia Institute’s research shows:
- ~5% of CVEs with CVSS Critical scores are ever observed being exploited
- ~10% of all CVEs ever see exploitation activity
- The top 1% of CVEs by EPSS score account for over 60% of observed exploitation
This is the core insight: a high CVSS score is necessary but far from sufficient to predict exploitation. EPSS captures what CVSS misses — the attacker’s interest in a vulnerability.
A CVE can be theoretically catastrophic (CVSS 9.8) but have an EPSS of 0.003 because it requires rare preconditions, targets obscure software, or has no public proof-of-concept. Conversely, a CVE rated CVSS 6.5 might have an EPSS of 0.85 because it’s trivial to exploit, affects widely deployed software, and has active exploitation observed.
Using EPSS in Practice
Accessing the data
# Download current EPSS scores (CSV, updated daily)
curl -O https://epss.cyentia.com/epss_scores-current.csv.gz
gunzip epss_scores-current.csv.gz
# Format: cve,epss,percentile
# CVE-2021-44228,0.97561,0.99999 <- Log4Shell
Most modern scanners (Grype, Trivy, Snyk) now include EPSS scores in their output natively.
A Practical Triage Framework
Combine CVSS severity with EPSS probability and CISA’s Known Exploited Vulnerabilities (KEV) catalog:
| Priority | Condition | Action |
|---|---|---|
| P0 — Fix now | In CISA KEV | Patch within 24–72h |
| P1 — Fix this sprint | EPSS > 0.2 AND CVSS ≥ 7 | Scheduled fix |
| P2 — Fix next sprint | EPSS > 0.05 AND CVSS ≥ 7 | Planned remediation |
| P3 — Monitor | CVSS ≥ 7, EPSS < 0.05 | Track, no immediate action |
| P4 — Accept | CVSS < 7, EPSS < 0.01 | Document and accept |
This model dramatically reduces the actionable backlog while focusing effort on what attackers are actually exploiting.
CISA KEV: The Ground Truth
The CISA Known Exploited Vulnerabilities catalog is a curated list of CVEs with confirmed active exploitation. For US federal agencies, these carry a mandatory patching timeline. For everyone else, they’re the clearest signal available that a vulnerability is being weaponized right now.
# Download KEV catalog as JSON
curl -O https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json
# Check if a specific CVE is in KEV
cat known_exploited_vulnerabilities.json | jq '.vulnerabilities[] | select(.cveID == "CVE-2021-44228")'
Integrating EPSS into Your Pipeline
With Grype
Grype outputs EPSS data natively in JSON format:
grype nginx:latest -o json | jq '.matches[] | {cve: .vulnerability.id, epss: .vulnerability.epss, severity: .vulnerability.severity}' | head -20
With a Custom Policy
Rather than using a scanner’s default severity thresholds, define a policy that combines CVSS, EPSS, and KEV:
def should_fail_build(vuln):
# Always fail on active exploitation
if vuln.in_kev:
return True
# High EPSS + medium+ severity = fail
if vuln.epss > 0.2 and vuln.cvss_score >= 7.0:
return True
return False
The Limits of EPSS
EPSS is a prediction model, not a guarantee. Some important caveats:
- Coverage lag — newly published CVEs have limited data; EPSS scores stabilize over days/weeks
- Context-blind — EPSS doesn’t know whether the vulnerable component is reachable from the internet, running in production, or in a test environment. Reachability analysis adds this layer.
- Not a replacement for patching — a low EPSS score doesn’t mean a vulnerability is safe to ignore indefinitely; it means it’s lower priority today
The most effective vulnerability management programs combine EPSS (exploitation likelihood), reachability analysis (is this path reachable?), and business context (how critical is this service?) — using each to filter and refine the actionable set.