EPSS
EPSS — the Exploit Prediction Scoring System — is a daily probability, from 0 to 1, that a CVE will see exploitation activity in the wild in the next 30 days. It is run by FIRST, the same body that maintains CVSS, and it answers the question CVSS deliberately doesn't: not "how bad would this be?" but "how likely is someone to try it soon?"
Score and percentile
Every scored CVE gets two numbers:
| Field | Example | Meaning |
|---|---|---|
epss |
0.04210 |
4.2% probability of observed exploitation in the next 30 days |
percentile |
0.88500 |
Scores higher than 88.5% of all CVEs EPSS currently scores |
The distribution is extremely skewed: the overwhelming majority of CVEs score well under 1%. That is why a score that looks small — 0.04 — can sit in the top eighth of everything published. Read the percentile when you want "how unusual is this?", and the score when you want "how likely is this?"
Why it changes every day
EPSS is a model, re-run daily on fresh inputs: exploit code appearing in public repositories or frameworks, mentions in security lists, detections from intrusion sensors, the vulnerability's age and vendor, and more. A CVE can sit at 0.002 for months and jump to 0.7 the week a working exploit is published. A CVSS base score, by contrast, is set once and rarely revised — so a triage list sorted by EPSS needs re-sorting, and a report should say which day's scores it used.
The model itself is versioned. FIRST released v3 in March 2023 and v4 in March 2025; scores from different model versions are not directly comparable, so don't diff this quarter's numbers against last year's.
EPSS, CVSS and KEV
| Question it answers | Published by | Changes | |
|---|---|---|---|
| CVSS | How severe would exploitation be? | FIRST (spec) | Rarely |
| EPSS | How likely is exploitation in the next 30 days? | FIRST | Daily |
| KEV | Has it been exploited already? | CISA | On adding |
KEV is the ground truth and should go first: if it's in the catalog, the prediction is moot. EPSS fills the much larger space of CVEs that aren't in KEV yet. A workable order is KEV, then EPSS above your threshold, then CVSS severity among the rest — always filtered by whether the vulnerable package is actually reachable in your deployment.
Picking a threshold
There is no official line. The trade is coverage against effort: a lower threshold catches more of what eventually gets exploited and sends more tickets. Common starting points are an EPSS score above 0.1 or a percentile above 0.95, tuned until the fix-now list is one a team can actually clear in a sprint.
Querying the API
FIRST publishes the scores free, no key required:
curl -s "https://api.first.org/data/v1/epss?cve=CVE-2021-44228,CVE-2023-4863" \
| jq -r '.data[] | "\(.cve) epss=\(.epss) pct=\(.percentile) \(.date)"'
Pass several CVE ids comma-separated to score a whole scan in a few calls,
and keep the date field next to the numbers you report. A full CSV of every
scored CVE is published daily for bulk joins.
Two catches when joining against scanner output: EPSS covers CVE ids only, so
GHSA- or PYSEC-led findings need mapping through their CVE
alias first (an OSV record lists them in aliases); and a
CVE published in the last day or two may not be scored yet.
Where the scan goes next
A ranked list only helps once the service owner sees it. Drop the scan JSON into the free Trivy viewer (Trivy and Grype), the npm audit viewer or the pip-audit / OSV-Scanner viewer, publish the report as a link, and comment on the high-EPSS rows directly — "EPSS 0.71 as of today, patch before Friday" pinned to the finding instead of lost in a thread.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.