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.

Open the Trivy viewer →

Related