A scanner reports a list of CVEs with scores such as 9.8 Critical or
5.5 Medium, and the question comes straight away: where do you start? This
lesson gives the three signals that let you triage: the CVE, the public
identifier of a flaw, the CVSS, which estimates its severity, and the
EPSS, which estimates the probability that it will be exploited,
complemented by the KEV catalogue of flaws that are actually exploited. It
is for a DevOps engineer or a developer who reads scan reports. The values
quoted were collected on 1 October 2026 from FIRST, the NVD and CISA.
What you will learn
- Decode a CVE identifier and know what it contains, and what it does not
- Interpret a CVSS score and recognise its limits
- Query the EPSS and the KEV catalogue for a vulnerability
- Prioritise a list of CVEs by combining severity, exploitation and exposure
- Explain why "0 CVEs" does not mean "0 risk"
- Link this triage to requirements SOCLE-VLN-INV-2 (in French) and SOCLE-VLN-VEX-2 (in French) of the SOCLE framework
What is a CVE?
A CVE (Common Vulnerabilities and Exposures) is the public identifier of a known vulnerability, assigned by the CVE programme. Before this catalogue, each vendor named the same flaw in its own way, and two alerts could describe the same problem without anyone knowing. With the CVE, a scanner, a vendor advisory and a ticket designate the same flaw with the same identifier, which lets you look for the fix and compare tools.
How do you read an identifier?
An identifier takes the form CVE-YEAR-NUMBER, for example CVE-2024-3094, the
backdoor discovered in the xz compression library. Contrary to a common
belief, the year is the one in which the identifier was assigned, not
necessarily the year of discovery or publication, and the number is a
simple sequence, with no meaning for severity nor precise chronological order.
CVE-2024-3094 was published in the NVD on 29 March 2024.
What a CVE contains, and what it does not
A CVE record carries an identifier, a short description of the problem and references (vendor advisories, fixes). It does not necessarily carry a score: that is added afterwards, by the NVD or by the vendor. Nor does it say whether the flaw is exploited in the wild, or whether a fix exists for your version. These three pieces of information come from other sources, described below.
CVSS: the severity score, from 0 to 10
The CVSS (Common Vulnerability Scoring System), maintained by FIRST, rates the theoretical severity of a flaw from 0 to 10. The score is computed from a vector that answers a few questions: through which access is the attack made (network, local, physical), is the attack complex, does it require prior privileges or a user action, and what is the impact on confidentiality, integrity and availability.
| Score | Level |
|---|---|
| 0 | None |
| 0.1 to 3.9 | Low |
| 4.0 to 6.9 | Medium |
| 7.0 to 8.9 | High |
| 9.0 to 10 | Critical |
The vector can be read and explains the score. Measured in the NVD:
CVE-2024-3094 (xz) gets 10.0 with the vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H: network attack, low complexity,
no privilege or user action, maximum impact. CVE-2021-23337, the lodash
flaw met in the SCA lesson, gets
7.2: its vector carries PR:H, the attacker must already hold high
privileges, which lowers the rating. Version 4.0 of CVSS has existed since
late 2023, but these two records only carry a version 3.1 score: always check
the version of the score you are comparing.
EPSS: will the flaw be exploited?
The EPSS (Exploit Prediction Scoring System), also published by FIRST, answers another question: what is the probability that a flaw will be exploited in the next 30 days? It is recomputed every day from real observations of malicious activity and the characteristics of the flaw. It complements CVSS instead of replacing it: a serious flaw that is rarely attacked and a medium flaw that is heavily attacked are not handled in the same order.
Querying the FIRST API
The public FIRST API answers without an account, in JSON. Here is the
response collected for CVE-2024-3094:
curl -s "https://api.first.org/data/v1/epss?cve=CVE-2024-3094"{ "status": "OK", "status-code": 200, "version": "1.0", "access": "public", "total": 1, "offset": 0, "limit": 100, "data": [ { "cve": "CVE-2024-3094", "epss": "0.859740000", "percentile": "0.997240000", "date": "2026-09-29" } ]}Two fields are read together. epss is a probability between 0 and 1:
0.859740000 reads as about 86%, not 0.86%. percentile places the flaw
relative to all the others: 0.997240000 means it is more likely to be
exploited than 99.7% of scored CVEs. The date field is a reminder that
the score changes every day: a score collected six months ago no longer
describes the situation.
The KEV catalogue: confirmed exploitation
The KEV (Known Exploited Vulnerabilities) catalogue from CISA, the US cybersecurity agency, lists the flaws whose exploitation is confirmed, no longer merely probable. Measured on 1 October 2026: it holds 1,730 entries. It contains CVE-2021-44228 (Log4Shell, added on 10 December 2021) and CVE-2023-44487 (HTTP/2 Rapid Reset), but not CVE-2024-3094: despite its CVSS of 10.0 and its EPSS of 0.86, the xz backdoor was spotted before being exploited at scale. KEV and EPSS therefore do not say the same thing, which is why you check both.
Scanners that display the EPSS
Not all scanners report this information. Measured on the node:14
image, an old Node.js image that piles up vulnerabilities: Grype 0.119.0
adds an epss field and a knownExploited marker taken from the KEV to each
match, and can sort by exploitation probability. Trivy 0.74.0 carries no
EPSS field in its JSON report. Here is an extract of Grype's output, sorted by
EPSS:
grype node:14@sha256:2cafa3fbb0b6529ee4726b4f599ec27ee557ea3dea7019182323b3779959927f --sort-by epssNAME INSTALLED FIXED IN TYPE VULNERABILITY SEVERITY EPSS RISKlibnghttp2-14 1.36.0-2+deb10u1 1.36.0-2+deb10u2 deb CVE-2023-44487 High 100.0% (99th) 78.8 (kev)node 14.21.3 *18.18.2, 20.8.1 binary CVE-2023-44487 High 100.0% (99th) 78.8 (kev)libsystemd0 241-7~deb10u9 (won't fix) deb CVE-2023-50387 High 100.0% (99th) 75.0libwebp6 0.6.1-2+deb10u1 0.6.1-2+deb10u3 deb CVE-2023-4863 High 100.0% (99th) 85.6 (kev)The EPSS column gives the probability and the percentile, (kev) flags a
confirmed exploitation, and RISK is a score specific to Grype, whose
formula belongs to it: use it to sort, not as an absolute measure. Note the
(won't fix) line: the distribution vendor will not fix this package, and the
only way out is to change the base image.
Combining the signals to decide
None of the three signals is enough on its own. The CVSS gives the severity if the attack succeeds, the EPSS gives the probability that it will be attempted, the KEV says that it already has been. A fourth signal is missing, one that only you know: the exposure of the component. The following table gives a starting policy, to adjust to your context.
| Situation | Signals | Action |
|---|---|---|
| Confirmed exploitation | present in the KEV | Fix immediately |
| Serious and probably exploited | CVSS ≥ 9 and high EPSS | Fix immediately |
| Serious, rarely exploited | CVSS ≥ 9, low EPSS | Fix this week |
| Medium but heavily exploited | CVSS 4 to 6, high EPSS | Fix this week |
| Low and rarely exploited | CVSS < 4, low EPSS | Schedule or accept |
Exposure adjusts each row: the same flaw moves ahead of the others on a public API and behind them on an isolated test environment. The SOCLE framework makes it a requirement: SOCLE-VLN-VEX-2 asks for a contextual prioritisation, rather than one based on CVSS alone.
Why "0 CVEs" does not mean "0 risk"
A "0 CVEs" report only means: among the known and catalogued flaws in the scanner's database, none matches the components it managed to detect. It covers neither flaws that are still unknown (0-days), nor components the scanner did not see, such as a binary copied by hand into the image, nor flaws that are published but not yet analysed by the database it queries.
The two scanners measured on node:14 illustrate this: Grype finds
2,032 matches there, and Trivy reports 1,455. They read neither the
same databases, nor the components in the same way. Combining two tools
reduces the blind spots, without removing them.
Above all, a large part of the risk has no CVE at all. A database reachable without a password, an API key published by mistake or the absence of backups are not software vulnerabilities, and no CVE scanner finds them. They fall under other controls: configuration audit with Lynis (in French), secret detection with Gitleaks, architecture review.
| Risk | Example | CVE? |
|---|---|---|
| Misconfiguration | Database open without a password | No |
| Human error | API key published on GitHub | No |
| Weak architecture | No backup, no monitoring | No |
| Unknown flaw | 0-day discovered tomorrow | Not yet |
What should you do with a list of CVEs?
A list of fifty CVEs does not call for fifty immediate actions. The triage is done with three questions, in this order, and each one shrinks the list before the next.
- Where is the component? Exposed on the internet, reachable by partners, internal, or confined to a test environment.
- What do the signals say? Presence in the KEV, EPSS, CVSS, in that order of weight.
- Which action? Fix, mitigate or accept.
The three actions are not equivalent. Fixing means updating the component, the only way out that removes the risk. Mitigating means reducing the exposure while waiting for the fix, through network filtering or an access restriction. Accepting means documenting why you are not fixing, for a limited period. The diagram below sums up this triage, from the raw list to one of the three actions.
On a fleet of servers, the same triage applies at scale: the Rudder CVE plugin (in French) detects vulnerabilities on each node and drives the update campaigns.
Key points
- A CVE is a public identifier; its year is the year of assignment, not necessarily of discovery.
- CVSS measures the severity if the attack succeeds; its vector explains the rating.
- EPSS estimates the probability of exploitation within 30 days;
0.86reads as 86%, and it changes every day. - The KEV lists confirmed exploitations: CVE-2024-3094, CVSS 10.0, is not in it.
- Grype displays the EPSS and the KEV; Trivy 0.74.0 does not carry the EPSS.
- "0 CVEs" covers neither 0-days, nor unseen components, nor risks without a CVE.
- You triage by exposure, then KEV, EPSS and CVSS; an acceptance is documented and expires.
- Evidence expected by SOCLE-VLN-INV-2 and VEX-2: an inventory enriched with KEV and EPSS, and a contextual prioritisation.
Knowledge check
Check that you have the essentials of this lesson. The questions only cover what has just been explained here.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: Securing npm, PyPI and Go dependencies
A new full quiz with random questions
Work again only on the questions you missed
Official resources
The four sources of this lesson are public and can be consulted without an account.
| Resource | What it is | Link |
|---|---|---|
| CVE Program | The official catalogue of identifiers | cve.org |
| NVD | CVEs enriched with their CVSS scores | nvd.nist.gov |
| EPSS | FIRST's exploitation probabilities | first.org/epss |
| KEV | Confirmed exploitations, by CISA | cisa.gov/known-exploited-vulnerabilities-catalog |