Skip to content
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after any top-up. Until Nov 30.

How it works

Reading a CVE: What a CVE Record Tells You and What It Does Not

A CVE record names the flaw and points to the vendor, and the vendor advisory sets the fixed version.

Beginner12 min readBy NotHoly

You read a news story saying a flaw with a CVE number is being exploited. Ten minutes later a colleague asks whether you are patched. The number is the one fact both of them agree on. It names one flaw. It does not tell you how bad that flaw is for your systems, which of your versions are affected, or what to install.

This article explains what a CVE ID is, who assigns it, what each field of a CVE record means, and how the National Vulnerability Database (NVD) adds to that record. The hands-on part reads one well-known record, CVE-2021-44228 (Log4Shell), field by field, from cve.org and from the NVD API. Then it opens the vendor advisory the record points to. The main thing to keep: the CVE record points you to the vendor advisory, and the vendor advisory is the source of truth for fixed versions.

If you have read What is a vulnerability, the terms will feel familiar. The lab sends read-only requests to two public services and one public web page.

What a CVE ID is

CVE stands for Common Vulnerabilities and Exposures. The CVE Program, as its overview describes it, identifies, defines and catalogs publicly disclosed cybersecurity vulnerabilities. Each vulnerability gets one entry, called a CVE Record, and the ID is the handle for that entry. It has the form CVE-YEAR-NUMBER. The year is the year the ID was reserved, which is often not the year the bug was written or fixed.

The ID is a name. It lets two people, or two tools, say "this one" and mean the same flaw. It carries no severity score, no list of affected products, no patch and no exploitation status. Those live in the record, and some of them come from other organizations.

Who assigns the IDs

The CVE Program works through CVE Numbering Authorities, or CNAs. The CVE site describes them as vendors, researchers, open source projects, CERTs, hosted services, bug bounty providers and consortia. Each one is authorized to assign IDs and publish records inside its own scope. When we checked the CNA page on 2026-11-08, it listed 564 CNAs, including 3 CNA-LRs (CNAs of last resort, for products no other CNA covers). The count changes, so check the page for the current number.

Scope is the word to remember. The Apache Software Foundation is the CNA for Apache projects, so the record for CVE-2021-44228 names it as the CNA. The CNA writes the title, description, affected products, references and problem types. Other parties can add data later, and that is where NVD comes in.

The fields of a CVE record

The field names below come from the CVE JSON record format. The JSON view on cve.org and the JSON from the CVE API use the same structure.

State and dates

The state tells you whether the entry is live. The record in this lab shows "state": "PUBLISHED". Rejected records also exist, so check the state first.

The CVE JSON carries three dates: dateReserved, datePublished and dateUpdated. For CVE-2021-44228 they are 2021-11-26, 2021-12-10 and 2025-10-21. NVD keeps its own dates. Its published value is 2021-12-10, and its lastModified value is 2026-08-11 in the response we pulled. The cve.org page shows a separate "Updated" date of 2023-04-03 from the CNA's provider metadata. Three sources, three "updated" dates. Compare them before you decide you have the latest text.

Description

The description is prose from the CNA. It should say what the flaw is, what triggers it and which versions it touches. The Log4Shell description gives the affected range, names the feature involved (JNDI lookups in configuration, log messages and parameters), says when the behavior was disabled by default, and states that log4net and other Apache logging projects are not affected. That last sentence saves an afternoon of patching the wrong thing.

Affected products and versions

This block is the most useful part of the record and the easiest to misread. Each version statement says whether a range is affected, unaffected or unknown, and it can express changes at specific version numbers.

The cve.org page shows the Log4j2 entry as a timeline: affected from 2.0-beta9, unaffected from 2.3.1, affected from 2.4, unaffected from 2.12.2, affected from 2.13.0, and unaffected from 2.15.0. A version takes the status of the most recent change point before it. The gaps are the point. "Everything below 2.15.0 is vulnerable" is wrong here, because 2.3.1 and 2.12.2 are listed as unaffected.

The lessThan field names the component, log4j-core*. The Apache advisory says that an application using only the log4j-api JAR is not affected. Read the component next to the version. The list is also only as complete as the CNA made it. Products that bundle the library may be missing, which is where the vendor advisory and NVD's configuration data help.

References

References are links to vendor advisories, mailing list posts, third-party write-ups and sometimes pages about exploitation. The cve.org page lists 53 references for CVE-2021-44228, each with a tag such as vendor-advisory, mailing-list, third-party-advisory or exploit. Read the vendor-advisory links first. Third-party pages give context, not fixed versions. The NVD copy of this record stores references in its own order, and its first five entries are all Packet Storm pages.

Weaknesses (CWE)

CWE is the Common Weakness Enumeration, a catalog of weakness types. CWE-20 is Improper Input Validation, and CWE-502 is Deserialization of Untrusted Data. A CWE says what kind of mistake led to the flaw. It does not name a product.

The CNA lists CWE-20, CWE-400 and CWE-502. The NVD record lists the same three, attributed to the Apache security address, and adds CWE-917, attributed to NVD. Keep the source column in view. You may disagree with an analyst's mapping, and you should know which mapping you are reading. CWE is also useful for grouping. A CWE search finds every deserialization flaw across products, which helps in code review and threat modeling.

Metrics

Metrics hold scores and assessments from different sources.

CVSS (Common Vulnerability Scoring System) gives a base score from 0 to 10, a severity label and a vector string listing the inputs: attack vector, complexity, privileges, user interaction, scope and impact. NVD's CVSS v3.1 entry for this record is 10.0, CRITICAL, with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H. The record also has an NVD CVSS v2.0 score of 9.3. The score describes the flaw under stated assumptions. It does not describe your exposure.

SSVC is a decision method that asks whether exploitation is active, whether the attack can be automated and how large the technical impact is. This record has an SSVC entry from a CISA coordinator source marking exploitation active, automatable yes and technical impact total.

KEV is the CISA Known Exploited Vulnerabilities catalog. The record shows a date added (2021-12-10), an action due date (2021-12-24) and a required action: apply updates, or remove the affected assets from the network. KEV means exploitation was observed. It is a different question from how severe the flaw is.

Metrics change. Read the source and the date with every number.

How NVD enriches a record

NVD is run by NIST, a separate project from the CVE Program. It takes CVE records and adds what the CNA may not have supplied: CVSS scores it calculates or confirms, CWE mapping, CPE configurations (machine-readable product and version matches), reference tags and a status field. The NVD API at services.nvd.nist.gov serves those enriched records. NIST's NVD dashboard page sits alongside the API documentation, so check it for notices before you assume enrichment is current.

The configuration block is the part most people never open. This record has 20 configuration blocks with 396 CPE match entries. The first entry is a Siemens firmware package, which shows the list covers products that embed the library, not only Apache's own releases. An empty or thin configuration can mean the analysis is unfinished, not that the product is safe.

The status here is Analyzed. That means NVD has processed the record. It does not mean NVD tested anything on your network. The lastModified date is 2026-08-11, long after publication, so a record you read last year may have changed.

Hands-on: read CVE-2021-44228 field by field

Requirements. A browser, curl (Git Bash on Windows includes it) and Python 3.12. jq is optional. Every request here is a read against a public service. Do not loop the NVD API. Without an API key, NVD limits requests in a short period, so run each command once.

Step 1: Read the CVE Record page

Open https://www.cve.org/CVERecord?id=CVE-2021-44228 and read it top to bottom. On the day this lab was run, it showed:

  • CNA: Apache Software Foundation
  • Published 2021-12-10, with a separate "Updated" date of 2023-04-03
  • Title: Apache Log4j2 JNDI features do not protect against attacker controlled LDAP and other JNDI related endpoints
  • CWE: 3 total
  • Product: Apache Log4j2, with the version statements described above
  • References: 53 total

Step 2: Pull the NVD record and filter the fields

The lab command, written for jq:

bash
curl -s 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-44228' | jq '.vulnerabilities[0].cve | {id, published, descriptions: .descriptions[0].value, weaknesses, references: [.references[0:5][].url]}'

jq was not installed on the machine used to test this lab, so the same filter ran in Python 3.12. Use this if you do not have jq either:

bash
curl -s 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-44228' -o nvd.json
python -c "import json; c=json.load(open('nvd.json', encoding='utf8'))['vulnerabilities'][0]['cve']; print(json.dumps({'id': c['id'], 'published': c['published'], 'descriptions': c['descriptions'][0]['value'], 'weaknesses': c['weaknesses'], 'references': [r['url'] for r in c['references'][0:5]]}, indent=2, ensure_ascii=False))"

Output observed from that command:

json
{
  "id": "CVE-2021-44228",
  "published": "2021-12-10T10:15:09.143",
  "descriptions": "Apache Log4j2 2.0-beta9 through 2.15.0 (excluding security releases 2.12.2, 2.12.3, and 2.3.1) JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0 (along with 2.12.2, 2.12.3, and 2.3.1), this functionality has been completely removed. Note that this vulnerability is specific to log4j-core and does not affect log4net, log4cxx, or other Apache Logging Services projects.",
  "weaknesses": [
    {
      "source": "[email protected]",
      "type": "Secondary",
      "description": [
        { "lang": "en", "value": "CWE-20" },
        { "lang": "en", "value": "CWE-400" },
        { "lang": "en", "value": "CWE-502" }
      ]
    },
    {
      "source": "[email protected]",
      "type": "Secondary",
      "description": [
        { "lang": "en", "value": "CWE-917" }
      ]
    }
  ],
  "references": [
    "http://packetstormsecurity.com/files/165225/Apache-Log4j2-2.14.1-Remote-Code-Execution.html",
    "http://packetstormsecurity.com/files/165260/VMware-Security-Advisory-2021-0028.html",
    "http://packetstormsecurity.com/files/165261/Apache-Log4j2-2.14.1-Information-Disclosure.html",
    "http://packetstormsecurity.com/files/165270/Apache-Log4j2-2.14.1-Remote-Code-Execution.html",
    "http://packetstormsecurity.com/files/165281/Log4j2-Log4Shell-Regexes.html"
  ]
}

Notice three things. NVD's published value carries a time, 10:15, with no time zone, while the CNA JSON gives midnight for the same day. The CWE entry added by NVD sits in its own block. And the first five references are third-party pages, so the vendor link has to come from a later step.

Step 3: Read the scores and the NVD status

bash
python -c "import json; c=json.load(open('nvd.json', encoding='utf8'))['vulnerabilities'][0]['cve']; print('lastModified', c['lastModified'], '| vulnStatus', c['vulnStatus']); [print(k, m['source'], m['type'], m['cvssData']['version'], m['cvssData']['baseScore'], m['cvssData'].get('baseSeverity'), m['cvssData']['vectorString']) for k in ('cvssMetricV31', 'cvssMetricV2') for m in c['metrics'][k]]"

Output observed:

text
lastModified 2026-08-11T19:33:44.513 | vulnStatus Analyzed
cvssMetricV31 [email protected] Primary 3.1 10.0 CRITICAL CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvssMetricV31 134c704f-9b21-4f2e-91b3-4a467353bcc0 Secondary 3.1 10.0 CRITICAL CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvssMetricV2 [email protected] Primary 2.0 9.3 None AV:N/AC:M/Au:N/C:C/I:C/A:C

The v2 entry has no severity label, which is normal for CVSS v2. The secondary v3.1 source is an identifier, not a name. The same identifier appears in the SSVC data next to a CISA coordinator role, so you can infer more than the field says. Write down what you can confirm and say which part is inference.

Step 4: Compare with the CVE JSON from the CNA

bash
curl -s 'https://cveawg.mitre.org/api/cve/CVE-2021-44228' -o cve5.json
python -c "import json; d=json.load(open('cve5.json', encoding='utf8')); print(json.dumps(d['cveMetadata'], indent=2))"

Output observed:

json
{
  "state": "PUBLISHED",
  "cveId": "CVE-2021-44228",
  "assignerOrgId": "f0158376-9dc2-43b6-827c-5f631a4d8d09",
  "assignerShortName": "apache",
  "dateUpdated": "2025-10-21T23:25:23.121Z",
  "dateReserved": "2021-11-26T00:00:00.000Z",
  "datePublished": "2021-12-10T00:00:00.000Z"
}

The assignerShortName names the CNA. The CNA's own metrics block has no CVSS score, only an other entry that says critical. The CVSS score you see comes from NVD.

Step 5: Open the vendor advisory

Open https://logging.apache.org/log4j/2.x/security.html. It redirects to logging.apache.org/security.html. The page has one section per CVE. The section for CVE-2021-45046 sits above the one for CVE-2021-44228.

In the text we fetched on 2026-11-08, the CVE-2021-44228 section gives the affected range as [2.0-beta9, 2.3.1), [2.4, 2.12.2) and [2.13.0, 2.15.0), and the fixed versions as 2.3.1 for Java 6, 2.12.2 for Java 7 and 2.15.0 for Java 8 and later. The CVE-2021-45046 section says the fix for CVE-2021-44228 in 2.15.0 was incomplete in some non-default configurations. Its mitigation line recommends 2.3.1 for Java 6, 2.12.3 for Java 7, or 2.16.0 for Java 8 and later.

Put the sources side by side:

Question CVE record (cve.org) NVD Vendor advisory
Which component? Apache Log4j2, log4j-core 396 CPE match entries in total log4j-core only; log4j-api alone is not affected
Which version is fixed? Unaffected from 2.15.0 Mirrors the affected ranges as CPE matches 2.15.0 for Java 8 and later, later found incomplete; 2.16.0 recommended
How severe? CNA metric "critical", no score CVSS v3.1 10.0 CRITICAL, v2 9.3 No score in the text we read
Exploited? No exploitation field in the CNA JSON we read KEV entry added 2021-12-10 Not stated in the text we read

A reader who stopped at the record's "unaffected from 2.15.0" would pick 2.15.0 as the target. The advisory says the 2.15.0 fix was incomplete and points to 2.16.0 for Java 8 and later. The record showed the CNA's version statements when they were written. The advisory shows what the vendor now says to install.

Common mistakes

Reading the CVSS score as your risk. The score assumes access and impact. Your exposure depends on whether the component is reachable and the setting is on. Use the score to sort work, then check reachability.

Stopping at the record's version range. The advisory is the source for the version to install. Check it every time.

Treating "not listed" as "not affected." A product missing from the list may still be affected. The list depends on CNA work and NVD analysis, and both take time.

Expecting a CVE for every problem. Many vendor fixes ship without an ID. A missing CVE is not proof of safety.

Mixing up dates. Reservation, publication, last update and last modification are different events from different sources. Name the source next to every date you quote.

Testing a CVE against systems you do not own. The lab is read-only. Reproducing a flaw on a target you do not control needs written permission from its owner. Use a lab you built, with the software version you are studying.

How to go further

Read the vendor advisory for each product you run, and subscribe to its security feed. For production systems, the vendor page is the record your change control should cite.

Group CWE types across the CVEs you follow, and check the CISA KEV catalog when a long list of new CVEs arrives in one week. KEV is a short list of flaws with confirmed exploitation, which makes it a useful filter.

Next in this series, What is CVSS explains how the 10.0 in this record is built, and why a base score is only one input to a priority decision.

Sources

Sources

  1. CVE Program overview
  2. CVE Numbering Authorities
  3. CVE Record CVE-2021-44228
  4. NVD vulnerability API documentation
  5. NVD dashboard
  6. Apache Log4j security page

More in Vulnerability intelligence