Skip to content

About

Turns a CVE ID into a plain-language explanation grounded in NVD data (description, CWE, CVSS, affected versions, references, CISA KEV status).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

cve-explain

Turns a terse CVE record into a plain-language explanation, grounded in NVD's own published data. No LLM in the loop — every line traces back to a specific field NVD returned.

$ python3 -m cve_explain explain CVE-2025-55182

# CVE-2025-55182

> ⚠ Actively exploited in the wild (CISA Known Exploited Vulnerabilities catalog)

In short: CVE-2025-55182 is a critical-severity vulnerability. It's classified
as CWE-502. Affects: react-server-dom-webpack (19.0.0, 19.1.0 through
19.1.1, 19.2.0); react-server-dom-turbopack (...); react-server-dom-parcel (...).
It is also listed in CISA's Known Exploited Vulnerabilities catalog...

## Severity — CVSS 3.1: 10.0 (CRITICAL)
`CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H`
- Attack vector: Can be attacked over the network — no physical or local access needed.
- Privileges required: The attacker needs no account or privileges on the target at all.
- ...

## What kind of bug this is
- CWE-502: Insecure Deserialization — the application reconstructs objects
  from untrusted input without proper checks, which can be abused to run
  arbitrary code or corrupt program state.

Why

A raw CVSS vector (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H) and a CWE number tell an expert everything and most people nothing. This tool bridges that gap using only structured NVD fields — the CWE ID, the CVSS metric letters, the affected version list, the CISA KEV flag — run through two small hand-written lookup tables (cvss.py, cwe_glossary.py). If NVD hasn't published a field, the output says so instead of guessing.

Install

pip install -r requirements.txt

Optional: set NVD_API_KEY to raise NVD's rate limit from 5 to 50 requests/30s. Request one here.

Usage

python3 -m cve_explain explain CVE-2025-55182   # fetch, explain, archive
python3 -m cve_explain explain CVE-2025-55182   # second run: served from archive, no re-fetch
python3 -m cve_explain explain CVE-2025-55182 --force
python3 -m cve_explain explain CVE-2025-55182 --json   # structured output for scripting/piping
python3 -m cve_explain list                      # everything explained so far

Each explain writes <CVE-ID>.md and <CVE-ID>.json under explanations/. Keep running it against new CVE IDs — by hand, from a feed, from cron, whatever fits your workflow — and that directory becomes a self-hosted, plain-language CVE archive you can commit to your own repo.

Optional: set GITHUB_TOKEN to raise the GHSA/patch-diff lookup's rate limit from 60 to 5000 requests/hour.

What each source actually adds

Source What it gives you When it's missing
NVD description, CWE, CVSS, affected versions, references, CISA KEV flag Required — lookup fails without it
EPSS (FIRST.org) data-driven probability of real-world exploitation in the next 30 days Very recently published CVEs aren't scored yet — section omitted
GHSA the actual fix commit, when the advisory links one, with real file-level diff stats Most CVEs don't have a resolvable commit link — section omitted

CVSS tells you how bad it is if exploited. EPSS tells you how likely it is to actually get exploited. The two often disagree, and reading only one of them is a common way to mis-prioritize.

Independent git-based version verification (--verify-git, optional)

python3 -m cve_explain explain CVE-2025-55182 --verify-git
python3 -m cve_explain explain CVE-2025-55182 --verify-git --clone-cache ~/.cache/cve-explain-clones

NVD's own "affected versions" field is a hand-maintained claim, and this tool has already found it unreliable in a real case (Log4Shell, below). --verify-git cross-checks it a different way: when the CVE has a resolvable GitHub fix commit, it clones that repo and asks Augur's provenance module to find, from the real commit history itself, when the vulnerable pattern was actually introduced — not "the last commit that touched the line" (classic SZZ's well-known weak point) — and which tagged releases genuinely contain it.

This is deliberately narrow and opt-in:

  • It only recognizes one bug shape so far (a fixed-size memcpy from a tainted char* parameter via one hop of pointer arithmetic).
  • It clones a real repository, so it's off by default — not something every explain call should silently pay for.
  • Most CVEs won't match; the report says so plainly ("Not applicable to this CVE: ...") instead of forcing an answer.

When it does match, you get a second, independently-computed opinion on the version range sitting right next to NVD's — worth a look, not a verdict to trust blindly over the other.

What each source actually adds

Limits, stated plainly

  • ~30 curated CWE entries. Anything not in CWE_GLOSSARY (cwe_glossary.py) links to the MITRE definition instead of a guess. Extend the dict as you hit gaps.

  • CVSS v3.0/3.1 only. v2 and v4 scores print with their raw vector string and no sentence breakdown — v4 uses a different metric set and isn't handled yet.

  • NVD's affected field is sometimes messy, and this tool works around specific cases it's actually hit, not a hypothetical list:

    • Pre-2015 CVEs often carry a literal vendor: "n/a", product: "n/a" placeholder instead of omitting the field — dropped rather than printed as "Affects: n/a (n/a and later)".
    • CVE-2021-44228 (Log4Shell) has a non-semver version boundary (lessThan: "log4j-core*") plus a list of version-by-version exceptions — degrades to "2.0-beta9 and later, see description" instead of a fabricated precise range.
    • The same reference URL sometimes appears twice under different NVD source IDs — deduped.

    All three were caught by running the tool against real CVEs, not invented as edge cases; see METHODOLOGY.md.

  • Explains, doesn't assess exploitability or generate PoCs. Out of scope by design.

  • No model in the loop, so no hallucination risk to guard against. Every sentence maps to a specific field from NVD, EPSS, or a real fetched commit diff. There's nothing here that's free-generated text, so there's nothing that needs a RAG pipeline or fact-checking step to keep honest.

What this is, and isn't

This is a read tool, not an analysis engine. It doesn't scan your codebase for the vulnerability, doesn't reverse-engineer binaries, and doesn't replace a proper vulnerability database like cve-search if what you need is bulk local querying across thousands of CVEs, or a threat-intel platform if what you need is "is this being used in a live campaign against my industry right now." What it does is turn one specific CVE ID into a complete, accurate, single-page answer in a few seconds, pulling three separate free public sources that most people don't think to cross-reference by hand every time.

About

Turns a CVE ID into a plain-language explanation grounded in NVD data (description, CWE, CVSS, affected versions, references, CISA KEV status).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages