A CVE is a public ID for a security flaw that is already known, so vendors, scanners and developers can all point at the same bug and check whether they have it. A zero-day is the opposite case: a flaw that attackers are using before the people who could fix it know it exists.
Vulnerabilities, exploits and patches
Three words get mixed up all the time:
- A vulnerability is a flaw in software that lets someone do something they shouldn't: read data they have no access to, run their own code, or crash the service.
- An exploit is the code or technique that uses a vulnerability. The vulnerability is the hole; the exploit is someone crawling through it.
- A patch is the fix, usually shipped as a new version, that closes the hole.
A vulnerability with no known exploit still needs fixing, but one with a public exploit is urgent. At that point anyone can use it, not only the person who found it.
What a CVE is
CVE stands for Common Vulnerabilities and Exposures. It is a public catalogue of known security flaws, run by the CVE Program and operated by the non-profit MITRE. Each entry, called a CVE record, has an ID, a short description, the affected products and versions, and links to advisories and fixes.
The point is a shared name. Without one, a vendor's advisory, a security scanner, a news article and your team's ticket might each describe the same bug differently, and nobody could be sure they meant the same thing. With a CVE ID, they all quote one string.
IDs are handed out by CVE Numbering Authorities (CNAs). These include large software vendors, open-source foundations and security companies, and most can assign IDs for flaws in their own products. So a vendor can reserve an ID for a flaw while it fixes it, then publish the fix and the CVE together.
Reading a CVE ID
Take CVE-2025-12345:
CVEsays what kind of ID it is.2025is the year the ID was assigned. It is not the year the bug was written, and not always the year it was made public.12345is the sequence number: the bug's licence plate. It has at least four digits and can be longer. It carries no meaning of its own, so a higher number is not a worse bug.
A CVE is not a severity score
A CVE says what the flaw is. How bad it is comes from a separate score, usually CVSS (the Common Vulnerability Scoring System), which rates a flaw from 0 to 10. The US National Vulnerability Database (NVD) adds scores and extra detail to CVE records. In CVSS version 3, 7.0 to 8.9 is High and 9.0 to 10.0 is Critical.
The score is generic: it describes the worst case for anyone running that version. Your own risk depends on whether you use the vulnerable feature, and whether an attacker can reach it. A better signal of urgency is whether the flaw is being exploited right now, which lists such as CISA's Known Exploited Vulnerabilities catalogue track.
From discovery to patch
Most CVEs follow a coordinated disclosure, roughly in this order:
- A researcher finds the flaw and reports it privately to the maintainer.
- The maintainer, or a CNA, reserves a CVE ID.
- A fix is written and released as a new version.
- The advisory and the CVE record are published, naming the affected and fixed versions.
- Everyone running the software upgrades.
Step 4 starts a race. Attackers read advisories too. They compare the old and new versions to see what changed, write an exploit, then scan the internet nonstop for servers that still run an affected version. Much of the damage happens in the gap between steps 4 and 5, when the fix exists and nobody has installed it.
That gap is also why forgotten software is dangerous. An old staging server or an app nobody maintains stays on the vulnerable version for good, which makes it part of your attack surface whether you remember it or not.
Zero-day exploits
A zero-day is a vulnerability that attackers know about before the vendor does, or before any fix exists. The name counts the days the developers have had to fix it: zero. A zero-day exploit is an attack that uses one.
That changes what you can do about it. Nobody has published an advisory, so you get no warning, and there is no CVE, or at least no public one. There is no patch either, so updating can't protect you yet. Scanners that match your dependencies against known CVEs have nothing to match.
Once a zero-day is discovered and disclosed, it usually gets a CVE and a patch, and it becomes an ordinary known vulnerability. From then on the risk moves to the systems that haven't patched. Security people sometimes call these 'n-day' vulnerabilities: fixed in principle, still open in practice.
You can't patch a flaw nobody has found, so the defence against zero-days is in layers:
- run each service with the least access it needs, so one breach doesn't open everything;
- keep the attack surface small, with nothing exposed that doesn't have to be;
- watch for unusual behaviour, such as a web server suddenly opening outbound connections;
- be able to patch quickly, so that when the fix does arrive, the window closes in hours, not weeks.
A worked example: Log4Shell
In December 2021, a flaw in Log4j 2, a very widely used Java logging library, was made public as CVE-2021-44228, nicknamed Log4Shell. If an app logged a string an attacker controlled, such as a username or a browser's User-Agent header, a specially crafted string could make Log4j fetch and run code from a server the attacker chose. It was given the highest CVSS score, 10.0.
What made it hard to deal with:
- Many teams didn't know they used Log4j. It often arrived as a dependency of a dependency, several layers below anything they had installed themselves.
- Scanning began almost at once. Attackers sent the crafted string to every server they could find, in every field that might get logged.
- The first fix was incomplete. A follow-up flaw got its own CVE, so teams had to upgrade more than once.
Teams that already kept an up-to-date list of every dependency they shipped could answer 'are we affected?' with a search, rather than a manual hunt through every project.
Finding known CVEs in your project
Package managers can check your whole dependency tree, including the dependencies of your dependencies, against databases of known vulnerabilities. In a Node project:
# Check the packages in package-lock.json
npm audit
# Upgrade to fixed versions
# that stay semver-compatible
npm audit fixIn Python, pip-audit does the same for the current environment:
pip install pip-audit
pip-auditRun checks like these in CI and on a schedule, not only when you remember, since a dependency you added months ago can gain a CVE tomorrow. Tools such as GitHub's Dependabot can open a pull request with the upgrade for you.
For each finding, ask three questions:
- Is the affected version actually in what you ship?
- Can an attacker reach the vulnerable code in your app?
- Is there a fixed version?
Upgrade first. If you can't yet, reduce the risk another way, such as turning off the vulnerable feature, and record why. Fewer dependencies, kept up to date, mean fewer findings to work through and fewer of the version clashes behind dependency hell.
Common mistakes
- Treating the CVSS score as your risk. A Critical flaw in code you never call can matter less than a Medium one on your login page.
- Checking only direct dependencies. Indirect dependencies often outnumber direct ones, and CVEs turn up in them too.
- Running
npm audit fix --forcewithout reading it. The flag allows major-version upgrades, which can break your app. - Assuming no CVEs means safe. A clean scan only covers flaws that are already known; it says nothing about zero-days.
- Mixing up CVEs and malicious code. A CVE is an honest mistake in real software. A malicious package is built to attack you on purpose, and needs different defences.
Key takeaways
- A vulnerability is the hole, an exploit uses it, and a patch closes it.
- A CVE is a public ID for a known flaw; in
CVE-2025-12345, 2025 is the year assigned and 12345 is the bug's unique number. - Publishing a CVE starts a race: attackers scan for unpatched versions, so patch quickly.
- A zero-day comes with no warning, no CVE and no patch, so it calls for layered defences.
- Scan every dependency automatically, including the indirect ones.