Risk and Prioritization

Inside the EPSS Model: What Data Predicts Exploitation

22 September 2026 8 min read

Before you wire a Service Level Agreement to an Exploit Prediction Scoring System (EPSS) threshold, you need to know what the number actually represents and how it is produced. EPSS gives you the estimated probability that a given CVE will be exploited in the wild in the next 30 days. It is not a severity score, it does not measure impact, and it is not a static label attached to a CVE forever. It is the daily output of a machine learning model maintained by the FIRST Special Interest Group (SIG), retrained on a moving window of exploitation evidence. Understanding the mechanics behind that number changes how you should consume it.

The problem EPSS was built to solve

CVSS answers “how bad would this be if exploited.” It says nothing about whether exploitation is likely. Organizations running CVSS-only triage routinely end up patching thousands of Critical and High findings a quarter when actual internet-wide exploitation activity concentrates on a few hundred CVEs a year. The FIRST SIG built EPSS to close that gap: given everything publicly knowable about a vulnerability on a given day, estimate the probability that it gets exploited before the next patch cycle even runs.

The framing matters because it defines what the score can and cannot tell you. EPSS predicts observed exploitation activity, not successful compromise, and not exploitation against your specific stack. A CVE affecting a component you do not expose to the internet can carry a high EPSS score and still be irrelevant to your environment. EPSS is a global prior. Your asset context is what turns it into a decision, which is why exposure data from attack surface management should sit next to the score before anyone acts on it.

Feature families the model consumes

EPSS v3, the version in production since March 2023, ingests over a thousand input variables per CVE, grouped into a handful of families:

  • CVE text and metadata: the description, referenced URLs, and their domains (a link to a Metasploit module or GitHub repo carries different weight than a link to a vendor advisory page).
  • Vendor and product signals: which vendor and product line is affected, and how frequently that vendor’s past CVEs have been exploited historically.
  • CWE category: the weakness classification (for example CWE-78 OS command injection versus CWE-200 information exposure), because exploitation base rates differ sharply by weakness class.
  • Published exploit code availability: whether a proof of concept or working exploit appears in Exploit-DB, Metasploit, or public code-sharing references tracked by the model.
  • Observed scanning and attack activity: whether the CVE identifier or associated signatures are already showing up in attacker or scanner traffic.
  • CVE age and publication timing: days since the CVE was published and since the CVSS score was assigned, because exploitation probability is not flat over a CVE’s lifetime.

None of these features is individually decisive. The model is a gradient-boosted tree ensemble that learns nonlinear interactions among them, for instance that a CVE with public exploit code, a CWE class historically associated with rapid mass exploitation, and a vendor with a large internet-facing footprint compounds risk multiplicatively rather than additively. This is also why EPSS resists simple manual approximation: you cannot recreate the score by eyeballing “has a PoC” and “is Critical.”

Where the ground truth comes from, and its sampling bias

Supervised learning needs labeled outcomes. EPSS’s labels come from exploitation activity data contributed by a coalition of intrusion detection vendors, honeypot networks, and threat intelligence organizations that participate in the FIRST SIG data-sharing arrangement. A CVE is labeled “exploited” in the training window if one of these sensor sources recorded an attack attempt referencing it, typically within 30 days of the observation.

This ground truth has a structural bias every consumer of the score should internalize. Sensor and honeypot telemetry is best at catching opportunistic, internet-scanning, mass-exploitation activity: worm-like propagation, botnet-driven scanning, commodity exploitation of internet-facing services. It is comparatively blind to targeted intrusion activity, exploitation inside segmented internal networks, and post-compromise lateral movement that never touches an internet-facing sensor. A CVE favored by a well-resourced targeted actor for a narrow campaign can carry a low EPSS score simply because it was never observed at sensor scale, not because it is safe. EPSS is a strong signal for internet-exposed, broadly scanned assets and a weaker signal for internally-scoped systems reached only through prior footholds. Treat a low score on an internal-only asset as “no evidence of mass exploitation,” not as “safe to defer.”

Retraining cadence and why cached scores go stale

EPSS publishes new scores for every scored CVE once a day. That daily refresh is not cosmetic. Three things move between publications: new exploit code gets published and indexed, new exploitation attempts get reported by sensor sources, and CVE age itself is a feature, so every CVE’s score shifts slightly each day even with no new evidence. A CVE with a stable 0.02 score last month can jump past 0.7 within 48 hours of a working exploit landing on GitHub. This is a documented, common pattern: score volatility spikes sharply in the days immediately following public PoC release.

The practical consequence is that any EPSS value written to a ticket, spreadsheet, or vulnerability record at discovery time is a snapshot, not a fact. If your remediation workflow reads EPSS once when a finding is created and never again, you will silently miss the exact scenario EPSS exists to catch: a previously low-risk, low-priority finding becoming actively exploited weeks after it was triaged and shelved. Prioritization logic needs to pull current EPSS on a schedule against every open finding, not just at intake. Platforms that automate this phase, such as SITEY, re-query EPSS for open findings on a recurring cycle inside vulnerability lifecycle tracking, so a score change after initial triage can re-open or re-rank a finding automatically instead of waiting for the next manual scan.

Calibration in plain terms

A model is “well calibrated” when its predicted probabilities match observed frequencies at scale. If you bucket every CVE the model scored at approximately 0.10, roughly 10 percent of that bucket should actually show exploitation activity within the following 30 days. FIRST evaluates this with the Brier score, a proper scoring rule that penalizes both overconfident and underconfident predictions, and publishes calibration curves alongside each version release.

Why does this matter operationally rather than academically? Because EPSS score distributions are heavily skewed: the overwhelming majority of CVEs score under 0.01, and only a small fraction ever cross into double-digit percentages. This means you cannot treat EPSS like a CVSS-style tier system with round-number cutoffs (0.3, 0.5, 0.7). A CVE at 0.05 is already unusually high relative to the population, while a CVE at 0.4 sits deep in the tail of things the model considers likely. Instead of picking an arbitrary threshold, use FIRST’s published coverage-versus-effort curves: they show what percentage of actually-exploited CVEs you catch (coverage) against what percentage of your total CVE population you would need to remediate (effort) at a given cutoff. A defensible policy sets the threshold where the coverage curve’s marginal return drops, then documents that threshold as a business decision, not a vendor default. When EPSS feeds AI-driven triage, it should be combined with exploit-availability flags and exposure state rather than consumed as a single number in isolation, because calibration is a population-level property and any individual score still carries prediction error.

Reading version changes without breaking your thresholds

EPSS has gone through three major model versions, and each one changed both the feature set and the score’s meaning:

Version Released Model Key change
v1 2021 Logistic regression Small feature set: CVE age, reference counts, a handful of vendor and CWE signals
v2 Feb 2022 Gradient-boosted trees (XGBoost) Added CVE description text features and more exploit-reference sources
v3 Mar 2023 Gradient-boosted trees, expanded feature set Over a thousand input variables, materially better coverage of low-scoring, long-tail CVEs

The critical operational point: scores are not comparable across versions. A 0.3 under v2 and a 0.3 under v3 do not represent the same underlying probability distribution, because the training data, feature set, and calibration surface all changed. If you hardcoded “auto-escalate anything above 0.3” as policy under v2 and the model quietly moved to v3, that threshold is no longer calibrated to the same population and your escalation rate will shift without any change in your actual environment.

Three habits prevent this from breaking your program. First, store the EPSS version alongside every score you persist, not just the numeric value, so historical comparisons are honest. Second, re-derive your threshold from the current version’s published coverage-effort curve whenever FIRST ships a major version, rather than carrying the old number forward. Third, keep an audit trail of score-driven decisions, including what version produced the score that triggered an SLA clock or an automated retest, so a post-incident review can distinguish “the model changed” from “the environment changed.” Vulnerability platforms that pin the EPSS model version in their evidence record for each finding make this reconstruction possible months later; ones that only store the raw float do not.

Putting it together

EPSS is a genuinely useful prior because it is trained on real exploitation telemetry rather than expert intuition, but it inherits every limitation of that telemetry: sensor-visible activity only, a 30-day exploitation window, and a score that moves daily. Use it to triage volume down from thousands of CVEs to a manageable queue, cross-reference it against actual exposure before treating a high score as urgent, refresh it continuously rather than at intake, and re-anchor your thresholds every time FIRST ships a new model version. Skip any of those four steps and the score stops meaning what you think it means.

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.

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing