EPSS, the Exploit Prediction Scoring System, gives you a single number between 0 and 1: the modeled probability that a given CVE will see observed exploitation activity in the next 30 days. Most teams get that part right. Where they go wrong is the second number that always ships alongside it, the percentile, and the two get merged into one mental model that produces bad prioritization calls. This is a field guide to reading both numbers correctly, plus what the score can and cannot tell you once you have it.
The one-sentence definition
EPSS is maintained by FIRST (the Forum of Incident Response and Security Teams) and answers exactly one question: given everything the model has learned from past exploitation patterns, vulnerability characteristics, and internet-wide telemetry, what is the probability that this specific CVE will be observed being exploited in the wild within the next 30 days. The current production model, EPSS v3, has been in use since March 2023 and pulls in signals such as CVSS vector components, CWE category, vendor, the age of the CVE, references to proof-of-concept code, presence in exploitation frameworks, and mentions across public sources.
That is the whole definition. EPSS does not score severity, does not score your exposure, and does not score whether exploitation would matter if it happened. It scores one thing: the likelihood of an exploitation attempt being observed, for that CVE, in that 30-day window, recalculated daily as new signals arrive.
Probability vs percentile: the pair everyone misreads
Every EPSS record ships two values, and they answer different questions:
- Probability (the epss field): a number from 0 to 1, read as a percentage. An epss value of 0.02 means a 2 percent modeled chance of observed exploitation in 30 days for that CVE, in isolation.
- Percentile: where that probability ranks against every other CVE scored on the same day. A percentile of 0.94 means the CVE’s probability is higher than 94 percent of the scored population, not that there is a 94 percent chance of anything.
The mistake almost everyone makes on first contact with EPSS is treating the percentile as a second probability, or worse, averaging it with the probability in their head to get a vague sense of “how bad.” They measure different things on different scales, and only one of them, the probability, is an actual likelihood. The percentile is a ranking device, useful for triage across a backlog, useless as a standalone risk statement.
Why a 0.08 probability can sit in the 94th percentile
This is the part that looks like a bug until you see the shape of the underlying distribution. EPSS scores are heavily right-skewed: the overwhelming majority of scored CVEs carry very low probabilities, often well under one percent, because most vulnerabilities never get weaponized or targeted at scale. Only a small slice of the population accumulates the signals, public PoC code, framework modules, active scanning chatter, that push a probability into double digits.
Because of that shape, a probability of 0.08 (8 percent) does not need to beat many CVEs to land near the top of the distribution. If the bulk of the population sits at 0.001 or lower, an 8 percent score can outrank the vast majority of scored vulnerabilities and still be, in absolute terms, an 8-in-100 chance rather than a near-certainty. Both facts are true at once: the CVE is unusually dangerous relative to its peers, and the raw probability of exploitation in any given 30-day window is still low in absolute terms. Prioritization logic that only checks “is this in the top 5 percent” is using percentile correctly. Prioritization logic that reads that same CVE and says “94 percent chance of exploitation” is using the wrong field.
The other trap: percentile is relative to that day’s population, not a fixed scale. Because FIRST periodically recalibrates the model and the pool of scored CVEs keeps growing, a percentile of 90 in one month is not scored against the same reference population as a percentile of 90 a year later. Do not store a percentile threshold in a policy document and assume it means the same thing indefinitely. Re-validate the threshold against current score distributions when the model version changes, which FIRST announces on the EPSS page.
What EPSS explicitly does not measure
EPSS is one input into risk, not a risk score by itself. Three things it does not touch, on purpose:
| Signal | Question it answers | What it ignores |
|---|---|---|
| CVSS base score | How severe is the outcome if this is exploited successfully | Whether exploitation is likely, and whether you are exposed |
| EPSS | How likely is an exploitation attempt in the next 30 days, across the internet | Impact if it happens, and whether the target is reachable by an attacker |
| CISA KEV | Has this CVE already been confirmed as exploited in the wild | Future likelihood; KEV is a historical, confirmed-exploitation catalog, not a prediction |
Impact is CVSS’s job, not EPSS’s. A CVE with a 0.4 probability and a CVSS base score of 3.1 is still a low-severity finding even though exploitation is comparatively likely. Your exposure is a separate question again: EPSS has no knowledge of whether the vulnerable service is internet-facing, sitting behind a WAF, segmented off from anything valuable, or already decommissioned. And compensating controls, virtual patches, EDR rules, network ACLs, are entirely outside the model. EPSS describes the population-wide attacker interest in a CVE; it says nothing about whether your specific instance of it is reachable at all. Attack surface mapping and network path analysis fill that gap. Platforms that run continuous attack surface management alongside network reachability checks, such as SITEY, join an EPSS feed against the asset graph so a high-percentile CVE only escalates when the affected asset is actually reachable, turning “this CVE is probably going to be attacked somewhere” into “this CVE is attackable on this specific host from this specific network position.”
Reading the daily CSV and the API response fields without misinterpreting them
FIRST publishes a full daily snapshot as a gzip-compressed CSV, linked from the EPSS page on first.org. The file opens with a comment line recording the model version and score date, for example a line beginning with a hash mark that states the model version string and the generation date, followed by a header row and then one row per scored CVE with three columns: cve, epss, percentile.
Two habits prevent misreads of that file:
- Always read the model version comment before comparing scores across files. A jump in a CVE’s score between two dates can mean the underlying model was updated, not that new exploitation signal arrived.
- Treat epss and percentile as columns that answer different questions, per the distinction above, rather than sorting by one and reporting the other.
For single-CVE lookups, FIRST exposes a REST API at api.first.org. A minimal query looks like this:
curl “https://api.first.org/data/v1/epss?cve=CVE-2023-4863”
The response is a JSON object with a data array; each entry carries cve, epss, percentile, and date fields, where date is the score generation date, not a CVE publication date. Two common integration mistakes: caching the response indefinitely (scores are recalculated daily, so a stale cache silently reports a probability that may be a month out of date), and comparing an epss value pulled today against a percentile pulled from a report generated weeks earlier. Pull both fields from the same response, on the same day, or the comparison is comparing two different reference populations. This is also why a one-time import is the wrong pattern: an AI triage step that pulls the feed on a schedule and re-scores open findings daily, the way SITEY’s triage phase does, catches drift that a static import misses. A finding that was 2nd-percentile at scan time can cross into the top decile a week later without anyone re-running the scan.
Three concrete questions EPSS answers well, and three it cannot
EPSS is a good fit for:
- Ranking a backlog you cannot fully patch this cycle. If you have 4,000 open medium and high findings and capacity to close 200 this sprint, EPSS percentile is a defensible way to pick which 200 get priority over the rest, assuming severity and exposure are already factored in separately.
- Deciding whether to pull a patch forward this week versus next month. Because the score refreshes daily, a sudden jump in probability for an already-known CVE is a legitimate signal to re-triage it, even if nothing else about your environment changed.
- Tracking whether attacker interest in a specific CVE is rising or falling over time. Plotting the same CVE’s score across several weeks shows momentum that a single snapshot cannot.
EPSS cannot answer:
- How much damage a successful exploit would cause in your environment. That requires CVSS impact metrics plus your own knowledge of what the affected asset does.
- Whether an attacker can actually reach the vulnerable service. That is an exposure and network-path question, answered by asset inventory and reachability analysis, not by a global statistical model.
- Whether you have already been targeted or compromised via this CVE. EPSS is a forward-looking population-level estimate; it has no visibility into your logs, your IDS alerts, or your incident history.
A workable policy: use CVSS for severity, EPSS for likelihood, and your own exposure data for reachability, then combine all three before a finding is auto-queued for patching. A common starting gate is CVSS at or above 7 combined with EPSS at or above 0.1, with anything on the CISA KEV list overriding both thresholds and going to the front of the queue regardless of score. Treat those numbers as a starting policy to tune against your own patch capacity, not a standard everyone must copy exactly. Automated pipelines that apply this kind of dual-threshold gate, including the gate logic inside patch management workflows in a system like SITEY, still need a human-set threshold behind them; the model gives you the two axes, the risk appetite is yours to set.
About SITEY
SITEY is an autonomous vulnerability management platform. It discovers, validates, prioritizes, remediates and re-tests vulnerabilities through an eight-phase automated pipeline, unifying output from 17 integrated scanners. SITEY is self-hosted: it runs in your own infrastructure and your findings are stored there. Outbound connections are limited to licence activation and the optional services you enable, such as an AI provider, CVE enrichment and patch catalogues. Pricing is 599 USD per month or 5,999 USD for a perpetual lifetime license. See pricing or how the platform works.