Risk and Prioritization

CVSS Threat Metrics and Exploit Code Maturity Explained

22 September 2026 9 min read

A CVSS Base score is frozen the day a CVE is published: attack vector, privileges required, and impact do not change. Whether attackers are actually using the flaw changes constantly, and that is exactly what the Base score cannot tell you. CVSS built a second layer to carry that information: the Temporal Metric Group in CVSS v3.1 (Exploit Code Maturity, Remediation Level, Report Confidence) and the leaner Threat Metric Group in CVSS v4.0 (a single Exploit Maturity metric). Almost no organization fills either one in, which means almost no CVSS score in a ticketing system reflects whether a working exploit exists at all.

Exploit Maturity in v4 vs Exploit Code Maturity, Remediation Level, and Report Confidence in v3.1

CVSS v3.1 splits threat context into three separate metrics under the Temporal group. Exploit Code Maturity (E) asks how mature and reliable available exploit code is. Remediation Level (RL) asks whether a fix exists yet, running from Unavailable through Workaround and Temporary Fix to Official Fix. Report Confidence (RC) asks how certain the reporting source is, from Unknown to Confirmed. All three multiply against the Base score, and all three default to a value of 1.00 when Not Defined, so an unscored Temporal metric never pulls the number down.

CVSS v4.0 collapses this into one Threat metric: Exploit Maturity (E), with four values instead of five: Attacked, Proof-of-Concept, Unreported, Not Defined. Remediation Level and Report Confidence are gone as scoring inputs. The rationale published alongside v4.0 is that RL and RC were rarely populated consistently and added complexity without changing prioritization outcomes often enough to justify it; patch availability is better tracked as an operational field in your own tooling than as a CVSS multiplier, and report confidence is now something an analyst weighs when deciding whether to trust a given Exploit Maturity value in the first place, rather than a separate multiplier.

Version Metric group Metrics Who typically scores it
v3.1 Temporal Exploit Code Maturity (E), Remediation Level (RL), Report Confidence (RC) The consumer organization; vendors and NVD publish Base only
v4.0 Threat Exploit Maturity (E) The consumer organization

The four values decoded: Attacked, PoC, Unreported, Not Defined

In v3.1, Exploit Code Maturity carries five values and five fixed multipliers against the Base score: Unproven (0.91), Proof-of-Concept (0.94), Functional (0.97), High (1.00), and Not Defined (1.00, scored identically to High so that skipping the field never understates risk). In v4.0 the same idea is expressed with four labels and no flat multiplier; instead the value shifts the score along a lookup table built from macrovectors, which is why an Exploit Maturity change in v4 can move a finding into a different severity band rather than sliding it a fraction of a point.

  • Attacked (v4) / High or Functional (v3.1): requires evidence of exploitation in the field, not just theoretical exploitability. Qualifying evidence includes a CISA Known Exploited Vulnerabilities (KEV) listing, a vendor advisory stating exploitation has been observed, incident response findings tied to the specific CVE, or telemetry showing in-the-wild scanning for that exact signature.
  • Proof-of-Concept: exploit code or a detailed technical write-up exists publicly and is reproducible, but there is no confirmed report of it being used against real targets. A merged Metasploit module, an Exploit-DB entry, or a conference talk with a working demo all qualify.
  • Unreported (v4) / Unproven (v3.1): no public exploit code, no credible write-up, no reported use. This is the correct default for a freshly disclosed CVE with only a vendor advisory and a CVSS vector, not “Not Defined.”
  • Not Defined: means you have not evaluated the metric, and it is scored as if it were the worst-case value on purpose, so that leaving it blank can never be used to argue a lower priority than the Base score already implies.

Why almost nobody populates temporal or threat metrics, and the damage that default does

NVD states plainly that it provides Base scores and does not compute Temporal, Threat, or Environmental scores. Most vendor advisories publish a Base vector and stop there. Most scanners and vulnerability databases ingest that Base vector and display it as “the” CVSS score. Because Not Defined is numerically identical to the worst-case option, nothing visibly breaks when a team never touches the field, so there is no forcing function that makes anyone build the workflow to populate it.

The cost shows up downstream, in the remediation queue. Two findings with an identical Base score of 9.8 land in the same bucket even though one has a working, unauthenticated exploit module and a KEV listing, and the other has never been reproduced by anyone outside the original researcher’s lab notes. A queue sorted on Base score alone treats both as equally urgent. In practice this produces one of two failure modes: teams patch everything on the same aggressive SLA regardless of real attacker interest, burning limited change windows on findings nobody is targeting, or teams get patch fatigue from that volume and start missing the SLA on the one CVE that actually has a KEV entry, because it is sitting in a list of a thousand other 9.8s that look identical on paper.

Sourcing maturity evidence: vendor PSIRT language, exploit repositories, incident reporting

Populating Exploit Maturity honestly means checking a short, specific list of sources rather than guessing:

  • CISA KEV catalog: the authoritative “this is being exploited” signal, published as a JSON feed that updates as CISA confirms active exploitation through incident response and partner reporting. Any CVE on this list should be treated as Attacked, full stop, regardless of what the Base score says.
  • FIRST.org EPSS: a daily-updated probability score from 0 to 1 estimating the likelihood of exploitation in the next 30 days, based on observed scanning and exploitation data across the internet. It is not the same metric as CVSS Exploit Maturity, but a sudden jump, say from 0.02 to 0.4 overnight, is itself a trigger to re-check the CVSS field.
  • Vendor PSIRT language: advisory wording that maps directly onto the CVSS values even when it is not phrased in CVSS terms. Phrases like “we have evidence of exploitation,” “exploitation has been detected,” or “a proof of concept is publicly available” correspond to Attacked, Attacked, and Proof-of-Concept respectively; treat vague language like “could potentially be exploited” as Unreported until something more specific shows up.
  • Exploit repositories: the Metasploit Framework module list, Exploit-DB, and Nuclei’s public template repository are the fastest way to confirm Proof-of-Concept status. A reviewed, merged module is stronger evidence than a raw script pasted into a GitHub gist.
  • Incident and threat intel reporting: ISAC bulletins, ransomware leak-site chatter naming a specific CVE, and internet-scanning telemetry from projects that track exploitation attempts by signature all support an Attacked determination even before a vendor advisory or KEV entry catches up.

Some platforms fold this lookup into the pipeline itself rather than leaving it to an analyst’s browser tabs. During discovery and scoring, SITEY checks each newly found CVE against the CISA KEV feed automatically and tags a match before anyone opens the finding, which removes the step where a genuinely urgent CVE sits untagged simply because nobody happened to check that day’s KEV update.

How a single maturity change swings the score, and the remediation clock with it

Run the v3.1 formula on a concrete example. Take a CVE with a Base score of 8.8, an official fix already shipped, and reasonable-confidence reporting at disclosure. At day zero, Exploit Code Maturity is honestly Unproven (0.91), Remediation Level is Official Fix (0.95), Report Confidence is Reasonable (0.96): 8.8 times 0.91 times 0.95 times 0.96 works out to roughly 7.3. That sits below an 8.0 “expedited patch” gate that many organizations set for their internal SLA tiers.

Three weeks later, working exploit code shows up in a public repository and reproduces cleanly. Exploit Code Maturity moves to Functional (0.97): 8.8 times 0.97 times 0.95 times 0.96 comes out to roughly 7.8, still under the gate but closing on it. Three weeks after that, CISA adds the CVE to KEV after confirming active exploitation. Exploit Code Maturity now sits at the top of the scale (1.00): 8.8 times 1.00 times 0.95 times 0.96 lands at roughly 8.0, crossing the same gate that determines whether change management treats this as an emergency patch or a scheduled one. The Base score never moved. The only thing that changed was whether anyone was checking the Exploit Code Maturity field.

In v4.0 the mechanism differs because there is no flat multiplier chain, but the effect is the same or sharper: moving Exploit Maturity from Unreported to Attacked can shift a finding across a macrovector boundary, moving it from a High severity band to Critical outright rather than nudging the decimal. Whichever version you run, the practical rule is the same: if your remediation SLA is keyed to a numeric CVSS threshold, that threshold is only as current as the last time someone recalculated the threat or temporal metric, not the last time NVD published the Base vector.

Keeping maturity fresh: the metric that must be re-evaluated, not set once

Base metrics describe the vulnerability itself and do not change. Threat and Temporal metrics describe the world around the vulnerability, and the world keeps moving after the finding is triaged. Treat the recheck as a scheduled, event-driven job rather than a one-time field on the intake form:

  1. Pull the CISA KEV JSON feed daily and treat any new match against an open finding as an automatic reset of its remediation deadline, independent of when it was first triaged.
  2. Pull EPSS scores daily; FIRST republishes the full set every day, and a large delta on an open finding is worth alerting on even before a KEV entry appears.
  3. Sweep exploit repositories weekly for internet-facing and crown-jewel assets, monthly for everything else, since a merged Metasploit module is a lagging but very reliable confirmation.
  4. Re-check on advisory updates, not just advisory publication; vendors revise wording as their own incident response teams learn more, and a second revision of the same advisory is a common place for exploitation language to first appear.

The same discipline applies to Remediation Level after a patch ships. Moving RL from Temporary Fix to Official Fix is itself a scoring event, and it should be confirmed against the live system rather than assumed from a closed change ticket. This is the same reasoning that pushes automated pipelines toward re-testing the specific finding after a patch job runs, instead of trusting the patch command’s exit code; SITEY’s retest and closure step re-checks the original finding directly before marking it resolved, which catches the case where the package manager reports success but the vulnerable service was never restarted. Feeding these KEV and EPSS deltas into an automated triage pass, the way SITEY’s AI triage stage does as part of its risk scoring phase, means every open finding gets re-scored the moment its exploit maturity changes, instead of waiting for whoever owns the spreadsheet to remember to check. Recording each change against the finding’s own history, rather than overwriting the current score in place, is also what lets a vulnerability lifecycle view answer “when did this actually become urgent” months later, and it is what makes a reporting export credible to an auditor who wants to see the maturity trail from open to patch to close, not just a single static number.

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