DedSec Security Research ·
A dependency scan flags two CVEs in the same service. One is CVE-2023-38545, a heap buffer overflow in curl's SOCKS5 proxy handshake, which NVD scores 9.8. The other is CVE-2023-4911, a buffer overflow in the glibc dynamic loader's handling of the GLIBC_TUNABLES environment variable, scored 7.8. A queue sorted by score puts curl first and lets glibc wait. CISA added CVE-2023-4911 to its Known Exploited Vulnerabilities catalog on 2023-11-21. As of the catalog version published on 2026-10-16, CVE-2023-38545 is not in it.
Neither number was wrong. They answer different questions, and the sort treated the answer to one as the answer to another. Three public signals get attached to a CVE, and each answers exactly one question:
None of them answers the question a triage queue is actually asking: should this team fix this instance before the others? That needs facts about your environment that no public feed can hold.
The sources here are the CVSS v3.1 and v4.0 specification documents, user guide and FAQ published by FIRST; FIRST's EPSS documentation and the daily EPSS score file; CISA's KEV catalog, its JSON feed and schema, its published inclusion criteria and Binding Operational Directive 26-04; and the NVD and CVE Program records for the CVEs used as examples. Figures that change daily are given with the date they were read.
The CVSS v4.0 specification says the Base score reflects a vulnerability's intrinsic characteristics, which are constant over time, and assumes the reasonable worst-case impact across different deployed environments. That sentence explains most of what goes wrong when CVSS is used as a priority. A base score is designed not to know whether the vulnerability is being exploited, whether you run the affected configuration, or whether the vulnerable system matters to you.
v3.1 structure. CVSS v3.1 has three metric groups. Base covers exploitability (attack vector, attack complexity, privileges required, user interaction) and impact (confidentiality, integrity, availability), plus Scope, which captures whether the impact reaches beyond the vulnerable component. Temporal covers Exploit Code Maturity, Remediation Level and Report Confidence. Environmental lets the consumer restate base metrics and weight the impact for their own systems.
v4.0 structure. CVSS v4.0 has four groups: Base, Threat, Environmental and Supplemental. The v4.0 user guide lists the changes that matter for prioritisation:
The defaults are the worst case. In v4.0, Exploit Maturity left at Not Defined is treated as Attacked for the score calculation. The Environmental security requirements (Confidentiality, Integrity and Availability Requirement) default to High when not set. So a base-only v4.0 score already assumes the vulnerability is being attacked and that the system is important. The user guide describes the Threat group as adjusting that worst-case score downward using threat intelligence, which only happens if someone supplies the threat intelligence.
The nomenclature says which question was answered. v4.0 asks that every numerical score be labelled with the groups used to produce it: CVSS-B for Base only, CVSS-BT for Base and Threat, CVSS-BE for Base and Environmental, and CVSS-BTE for all three. The specification also says that Threat and Environmental metrics are the consumer's responsibility, and that assessment providers such as product maintainers and NVD typically provide only CVSS-B. The user guide has a section headed "CVSS Base Score (CVSS-B) Measures Severity, not Risk", and the v4.0 FAQ says CVSS-B scores are not risk and should not be used alone for patch prioritisation.
That is why scanner output usually shows a base score. A scanner matches a package version to an advisory and copies the score the advisory carries. It has no Threat data unless someone wires it in, and it cannot know your Environmental values. The "Critical" in a scanner column is almost always a CVSS-B label, whichever version produced it.
A CVE record is published by a CVE Numbering Authority, usually the vendor or a coordinator, and the CNA may or may not include a CVSS vector. Other parties add their own. NVD publishes its assessment, and its API labels NVD's own score Primary and other sources' scores Secondary. CISA adds vector strings and SSVC decision values through its Vulnrichment programme, which appears in CVE records as the CISA-ADP container.
CVE-2023-38545 shows how far they can drift. Read on 2026-10-19:
Neither scorer is doing anything wrong. The specification asks for a reasonable worst case, and reasonable people read the same advisory differently. Distributions add a third layer: Debian, Ubuntu and Red Hat rate issues in their own builds and configurations, and some scanners prefer those ratings over NVD's. The post on container image CVE counts has an example rated Critical by NVD and Low by Debian. The v4.0 user guide also allows several base scores for one vulnerability when it behaves differently across versions or platforms, and says that when only one is provided, the highest applies.
The practical consequence: a severity sort is only stable if every finding's score comes from the same source, and the source and vector are stored with the finding. Two tools that disagree about "Critical" are often disagreeing about which scorer to trust.
The v4.0 user guide has explicit guidance for vulnerabilities in libraries. The analyst cannot know how the library will be used, so they assume the reasonable worst case: an image-parsing library is assumed to receive untrusted images over the network, and to run with high privileges. It then says that an implementation embedding the library must be re-assessed for that implementation. If the product only processes local files, the attack vector becomes Local. If it never invokes the faulty function, the severity for that implementation is 0.
That is the specification itself saying that a dependency's base score describes the most exposed caller anyone can imagine, not your application. The question it leaves open, whether your code reaches the vulnerable function, is the one the post on reachability is about.
The Exploit Prediction Scoring System, maintained by an EPSS Special Interest Group at FIRST with scores generated by Empirical Security, publishes a number between 0 and 1 for every scored CVE, every day. FIRST's documentation defines it as the estimated probability that exploitation activity associated with the CVE will be detected, recorded and shared by EPSS's data partners in the next 30 days.
Each part of that definition matters.
Activity, not success. The training labels come from endpoint malware telemetry, honeypots, IDS and IPS telemetry and threat intelligence feeds. FIRST's documentation is explicit that these record attempts. A honeypot hit and an exploit blocked by an IPS count as activity.
Observed by partners. EPSS learns from what its sensors see. FIRST lists observation bias among the model's known limitations: exploitation that generates no telemetry is not in the training data.
Population-level. The FAQ says EPSS does not measure how much damage exploitation would cause, or whether it affects your environment, and does not account for compensating controls. A CVE in software you do not run can score high, and one deployed widely across your estate can score low.
Not a severity. EPSS uses the individual CVSS metrics as input features but ignores the CVSS score, and it defines no "critical" or "high" bands. FIRST's guidance also says not to multiply EPSS by CVSS. EPSS is a calibrated probability and CVSS is an ordinal score, so the product has no interpretable meaning.
The EPSS file carries two numbers per CVE. The score is the probability. The percentile is the CVE's rank among all scored CVEs: a CVE at the 90th percentile has a higher score than 90% of them. They are easy to confuse because both run from 0 to 1, and they mean very different things.
The distribution is heavily skewed. The 2026-10-18 file, produced by model v2026.06.15, scores 390,807 CVEs. Its median score is 0.00647 and its mean 0.0266. 4.4% of scored CVEs are at or above 0.1 and 1.1% at or above 0.5. FIRST's FAQ makes the same point from the other side: a probability of 0.10 currently sits around the 95th percentile, and in any 30-day window EPSS observes exploitation activity for roughly 2.5 to 3% of published CVEs.
So a score of 0.05 is not "low". On its own it means a 1 in 20 chance of observed activity in 30 days, and it ranks above most of the population. Reading the percentile as the probability makes almost everything look urgent. Reading the score as a school grade makes almost nothing look urgent.
Scores are recomputed every day; FIRST says they are typically published shortly after 13:30 UTC. The model itself is not retrained daily. A score changes because its inputs changed: exploit code appeared, a detection signature was published, references accumulated. FIRST notes that observed exploitation feeds model training, not daily scoring, so a widely reported attack yesterday does not directly move today's score.
The model is versioned, and the first line of each daily CSV names the version and score date. On the file read for this post it is "#model_version:v2026.06.15,score_date:2026-10-18T12:03:10Z". FIRST lists five versions: v1 from 2021-04-14, v2 from 2022-02-04, v3 from 2023-03-07, v4 from 2025-03-17 and v5 from 2026-06-15. Its data page warns that each version shifted scores on the day it started publishing, so a time series across that boundary shows a methodology change, not a change in the vulnerability. The API can return a score as of a past date, which is how a decision taken last month can be reconstructed.
Two operational consequences. A ticket that stores "EPSS 0.12" without a date and model version cannot be audited later. And a threshold tuned against one model version needs checking after the next one.
FIRST documents these itself:
The Known Exploited Vulnerabilities catalog is a list, not a score. CISA adds a vulnerability when three criteria are met:
CISA's criteria page defines active exploitation as reliable evidence that malicious code was executed on a system without the owner's permission, and includes attempted exploitation, explicitly including successful code execution on a honeypot. It also lists what does not count: scanning, security research of an exploit, and the existence of a proof of concept. A public PoC is neither sufficient nor required.
It is history, not a census. Each criterion is a filter. A vulnerability exploited before it has a CVE ID, or with no remediation to point to, cannot be listed yet. Exploitation that nobody reports reliably to CISA is not listed. A malicious package without a CVE can never be listed, which is one reason the post on malicious packages treats malware as a separate channel. FIRST's EPSS FAQ puts KEV at roughly 0.5% of published CVEs, against the 2.5 to 3% for which EPSS's partners observe activity in any 30-day window. Those are different measurements over different windows, but the gap is the point: absence from KEV means CISA has not listed it, not that nobody has exploited it.
The catalog is published as JSON and CSV at cisa.gov and mirrored in CISA's kev-data repository on GitHub, whose README says the two are kept in sync within minutes. The JSON read for this post has catalogVersion 2026.10.16, dateReleased 2026-10-16 at 17:15:48 UTC and a count of 1,748 entries. Each entry carries the CVE ID, vendor, product, name, a short description, dateAdded, requiredAction, dueDate, notes, CWE identifiers and two fields worth reading closely:
Store catalogVersion alongside any decision that depended on KEV status. CISA updates the catalog when entries are added or changed, and "it was not in KEV when we deferred it" is only checkable if you recorded which catalog you looked at.
Much existing guidance says KEV due dates apply to US federal civilian agencies under BOD 22-01. That changed on 2026-06-10, when CISA issued Binding Operational Directive 26-04, "Prioritizing Security Updates Based on Risk", which supersedes and revokes BOD 22-01 and BOD 19-02. It applies to Federal Civilian Executive Branch agencies. It says the criteria for KEV inclusion remain unchanged.
What changed is how a deadline is derived. Within 180 days of issuance, agencies must remediate within the timelines in the directive's table, which sets the deadline per asset from four decision points: whether the asset is publicly exposed, whether the CVE is in KEV, whether exploitation is automatable by an adversary, and whether exploitation gives partial or total control of the asset. CISA publishes the last three for every CVE through Vulnrichment. CISA does not publish exposure; the agency determines it, with CISA's Cyber Hygiene scanning or third-party asset and vulnerability management tools as possible inputs. A few rows from its timeline table:
The directive says timelines move when facts change. Taking an asset off the internet changes exposure and lengthens its timeline. A CVE being added to KEV shortens it. Of the 131 entries added to the catalog from 2026-06-10 onward, the dueDate field is 3 days after dateAdded for 108 and 14 days after for 23.
Two things are worth noticing. First, for everyone outside the federal civilian scope, dueDate is a reference, not an obligation. Second, the directive does not use a CVSS score anywhere in the table. It uses technical impact, which the directive describes as similar to the CVSS base score's concept of severity, as one input of four, next to exposure and exploitation. The CVSS v4.0 FAQ now points to BOD 26-04 as a rubric that other organisations can adapt.
The CVEs from the opening, plus one more, scored by all three, as read on 2026-10-19 (KEV catalog 2026.10.16, EPSS scores for 2026-10-18):
A CVSS sort puts curl first and Rapid Reset last. KEV puts the other two ahead of curl. EPSS says all three are in the top 1% of scored CVEs. And none of the three signals says whether you are affected. CVE-2023-38545's description says the overflow occurs when curl passes the host name to a SOCKS5 proxy for it to resolve, so it depends on how curl is configured. CVE-2023-4911 needs a local attacker able to run a SUID binary with a crafted environment variable. Rapid Reset matters wherever your own software terminates HTTP/2. Each is a question about your deployment, and only you can answer it.
The disagreement is also visible across the whole catalog. Joining the 2026-10-18 EPSS file to KEV version 2026.10.16, 1,747 of the 1,748 KEV CVEs have a score. Their median is 0.49, but 460 of them score below 0.1 and 62 below 0.01. FIRST's guidance covers this case directly: a low EPSS score on a KEV-listed CVE is not a contradiction, since one is history and the other a 30-day forecast, and when a CVE is in KEV, follow KEV.
What follows is general practice, not a description of any product's ranking. It mirrors the shape of BOD 26-04: exploitation evidence and exposure decide urgency, and severity refines it.
0. Presence. Is the affected version actually installed and loaded, according to the right advisory data? Distribution backports make upstream version matching wrong, and the container post covers that failure. Nothing below matters for a finding that is not real.
1. KEV, present and reachable. Treat it as being exploited. If the asset is internet-facing, or the vulnerable path can be reached from untrusted input, it goes to the front, and for a total-control bug on an exposed host it is worth asking whether you have already been compromised, not only how to patch.
2. Not in KEV, but above a deliberately chosen EPSS threshold, and exposed or reachable. Choose the threshold from capacity. Count how many of your open findings sit above candidate thresholds, and pick the one your team can actually clear in the time you would want. Write the threshold, the date and the model version down, and revisit it after a model change.
3. Everything else present and reachable, ordered by consequence: what the vulnerable system holds, what it can reach, and whether exploitation is automatable. This is where CVSS earns its keep, preferably as a vector read against your deployment rather than a single number.
4. Present but not reachable. Fix it in the next routine upgrade. It does not leave the list, and it moves up if reachability changes or the CVE enters KEV.
The public signals are the same for every organisation. What makes a CVE urgent for you is local:
If you do write CVSS-BTE scores, label them as such. A "7.2" next to a "9.8" means nothing if one is CVSS-BTE for your system and the other is someone else's CVSS-B.
Sorting by CVSS alone. It ranks by worst-case technical impact in a generic environment. It will put a network-reachable bug nobody exploits ahead of a local one in KEV, as in the opening.
Mixing score sources. If one tool takes NVD scores and another takes vendor or distribution scores, the same CVE lands in different bands, and "how many Criticals do we have" depends on which tool you asked. Store the source and vector with the score.
Using EPSS as a threshold nobody chose. A cut at 0.5 sounds cautious and, on the 2026-10-18 distribution, selects about 1.1% of scored CVEs. It would also exclude about half of KEV entries (877 of the 1,747 that have a score). A cut at 0.1 excluded 460 KEV entries on the same day. If the threshold was not derived from capacity and coverage, it is a guess.
Reading the percentile as a probability. The 95th percentile is around a 10% probability, not 95%.
Multiplying EPSS by CVSS. FIRST's documentation says directly that the product has no interpretable meaning.
Treating "not in KEV" as "not exploited". KEV requires a CVE ID, reliable evidence reported to CISA and a remediation action. Plenty of exploitation fails one of those, or has not been listed yet.
Reading ransomware "Unknown" as "No". The field records confirmation. Unknown means CISA has not confirmed ransomware use.
SLAs by severity band. "Critical in 15 days, High in 30" gives a High KEV entry on an internet-facing host twice as long as a Critical that nobody exploits on an internal batch server. It also fixes the clock at the moment the finding was opened. BOD 26-04 keys deadlines to exposure, exploitation, automatability and impact, and moves them when those facts change. A band SLA can do the same if the band is recomputed when a CVE enters KEV, when an asset's exposure changes, or when reachability is established, and if the finding records why its deadline moved.
Scoring once. KEV changes when CISA updates it, EPSS changes daily, and NVD records are modified. A finding's priority at the time of the scan is not its priority now.
AppSecD's security intelligence correlates advisories from 18 feeds against the versions, manifests and repositories actually present in your software estate, with CISA KEV highlighted and a blast-radius view per CVE. Its CVE reachability answers whether the vulnerable code path can be reached at all, and findings are deduplicated across scans and carry ageing, an SLA and an owner. Maphra's Threat Intelligence Hub correlates advisories, CVE feeds and exploit intelligence against the assets you actually operate, so a CVE only raises an alarm when it touches your surface. The triage order and failure modes in this post are general practice, not a description of how either product scores or ranks findings.
CVSS tells you how bad a vulnerability could be, EPSS how likely activity against it is, and KEV whether exploitation has been seen. Whether it is urgent for you depends on exposure, reachability and what the system holds, and you are the only one with that information.