Filter your company's products and rank real-world CVE risk (CVSS + EPSS + CISA KEV + public exploits), with AI-written exploitability analysis.
Project description
CVE Risk Analyzer
A terminal tool that watches the products your company uses, pulls fresh CVEs, and ranks them by real-world exploit risk — not just raw CVSS. It blends severity, exploit probability (EPSS), active-exploitation status (CISA KEV), and public exploit-code availability, then uses Claude to explain how easily each one can actually be exploited: preconditions, limitations, and a verdict.
Data sources (all keyless except Claude)
| Source | Purpose | Key |
|---|---|---|
| Shodan CVEDB | primary discovery: CVE data + CVSS + EPSS + KEV in one call | none |
| FIRST.org EPSS | exploit-probability backfill for any CVE missing it | none |
| GitHub Search | public exploit / PoC detection | optional GITHUB_TOKEN |
| NVD (NIST) | authoritative CVSS + structured CPE version ranges | optional NVD_API_KEY |
| OpenCVE | structured CPE version ranges + CVSS/KEV/CWE | optional OPENCVE_API_TOKEN |
| Anthropic Claude | exploitability narrative & verdict | ANTHROPIC_API_KEY |
Without an Anthropic key the tool still runs in rule-based mode (scores and signals only, no narrative).
NVD and OpenCVE are optional and auto-activate when their credentials are set.
CVEDB handles discovery; NVD and/or OpenCVE then overlay authoritative CVSS scores
and structured CPE version ranges onto the top-ranked CVEs (enrichment by
CVE-ID, so they always hit the CVEs you actually see). The run header shows which
sources are active (e.g. sources: CVEDB + EPSS + OpenCVE).
- NVD — free key at https://nvd.nist.gov/developers/request-an-api-key
- OpenCVE — free account at https://app.opencve.io; create an Organization
API token (Bearer) and set
OPENCVE_API_TOKEN. Basic Auth (OPENCVE_USERNAME+OPENCVE_PASSWORD) is also supported (legacy).
When either source supplies structured version ranges, --version becomes a
precise range match (versionStartIncluding ≤ you ≤ versionEndIncluding)
instead of a text heuristic. Everything works fully without these keys.
Install
Recommended — install the cve-analyzer command with pipx
(isolates its dependencies from your other Python tools):
pipx install cve-risk-analyzer # once published to PyPI
# or, from a local checkout:
pipx install .
Or with plain pip / for development:
pip install -e . # editable install from a checkout
After installing, the command is available anywhere:
cve-analyzer guide # how-to
cve-analyzer where # shows where state + keys live, and which keys are set
Keys & state
Run cve-analyzer where to see the exact paths. State (your watchlist) lives in
an OS-native per-user data dir:
- Windows:
%LOCALAPPDATA%\cve-analyzer - macOS:
~/Library/Application Support/cve-analyzer - Linux:
~/.local/share/cve-analyzer
Put API keys in a .env there, in a .env in your current folder, or export them
as environment variables. Only ANTHROPIC_API_KEY is needed for AI analysis;
NVD_API_KEY, OPENCVE_API_TOKEN, and GITHUB_TOKEN are optional and enrich
results when present.
The examples below use
python -m cve_analyzer(works from a source checkout). Once installed,cve-analyzeris the equivalent shorter command.
Usage
# Not sure where to start? Print the built-in how-to for every command:
python -m cve_analyzer guide
# Build your watchlist — product tokens are auto-resolved (e.g. "Cisco IOS XE" -> ios_xe)
python -m cve_analyzer add "Apache Tomcat"
python -m cve_analyzer add "Cisco IOS XE"
python -m cve_analyzer add "OpenSSL" --version 3.0
python -m cve_analyzer add "Some Product" --token exact_cpe_token # manual override
python -m cve_analyzer list
python -m cve_analyzer remove "OpenSSL"
# Track a WHOLE vendor (all their products) — keyless, via NVD
python -m cve_analyzer add-vendor cisco # e.g. 6,600+ Cisco CVEs across all products
python -m cve_analyzer remove cisco --vendor
# Report — prints the risk table to your terminal AND writes a shareable file
python -m cve_analyzer report # rank all + AI on top findings
python -m cve_analyzer report --no-ai # rule-based only, no API cost
python -m cve_analyzer report --open # also open the HTML in your browser
python -m cve_analyzer report --no-preview -f json -o findings.json
python -m cve_analyzer report --top 5 --limit 20
# Filters
python -m cve_analyzer report --since 90d # only CVEs published in last 90 days
python -m cve_analyzer report --since 2025-01-01 # ...or since an absolute date
python -m cve_analyzer report --version 3.0 # only CVEs affecting that version
# Report on specific CVEs (skips the watchlist)
python -m cve_analyzer report CVE-2023-20198 CVE-2024-21762 -o crit.html
# Deep-dive one CVE in the terminal (use --deep for the strongest model)
python -m cve_analyzer analyze CVE-2023-20198
python -m cve_analyzer analyze CVE-2024-21762 --deep
report is the main command: it prints the ranked risk table (with a legend)
to the terminal and writes an HTML/JSON file. Use --no-preview for file-only,
or analyze to inspect a single CVE in the terminal.
Filters & flags
| Flag | Commands | Meaning |
|---|---|---|
--since |
report | Nd/Nw/Nm/Ny or YYYY-MM-DD. Switches to newest-first fetching so recent CVEs surface. |
--version / -v |
report, add | On report: keep CVEs affecting the version (precise with NVD/OpenCVE, else heuristic). On add: store a version for the product. |
--limit / -l |
report | Max CVEs fetched per product (default 15). |
--top / -t |
report | How many top-ranked CVEs get the AI narrative (default 10). |
--ai / --no-ai |
report | Toggle the Claude narrative (--no-ai = zero API cost). |
--preview / --no-preview |
report | Print the table + AI cards to the terminal (default on). |
--legend / --no-legend |
report | Show/hide the how-to-read key. |
--open |
report | Open the generated HTML in your browser. |
--deep |
analyze | Use the strongest model (Opus) for a single CVE. |
--token |
add | Override the auto-resolved CPE product token. |
On
--versionprecision: with an NVD or OpenCVE key set, version filtering uses structured CPE ranges for precise matching. Without either, the keyless CVEDB source has no version data, so it falls back to a best-effort text match against the CVE description (a narrowing aid, not authoritative).
Risk score
Transparent weighted blend (tune in scoring.py):
risk = 10 * (0.40*CVSS/10 + 0.30*EPSS + 0.20*KEV + 0.10*PoC)
Project layout
cve_analyzer/
cli.py # commands
config.py # env + paths (UTF-8 fix for Windows)
watchlist.py # product watchlist storage
models.py # normalized Vuln record
scoring.py # composite risk
filters.py # --since date window + --version heuristic
analysis.py # Claude narrative
render.py # slick terminal output (rich)
report.py # HTML / JSON export
sources/
cvedb.py # Shodan CVEDB client + token resolver (discovery)
nvd.py # NVD/NIST client — authoritative CVSS + CPE ranges (optional key)
opencve.py # OpenCVE client — CPE ranges + CVSS/KEV/CWE (optional token)
epss.py # FIRST.org EPSS backfill
poc.py # GitHub PoC detection
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cve_risk_analyzer-0.1.1.tar.gz.
File metadata
- Download URL: cve_risk_analyzer-0.1.1.tar.gz
- Upload date:
- Size: 25.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4d6f483044afca09a37962ed641b7842ec6a5db336a5f455c94187925fe5292
|
|
| MD5 |
f582bfc0bec3ebfdcd7f027bc303ab7d
|
|
| BLAKE2b-256 |
b17afce781e8fa462feb9f13b7b83a22f69abcf7c8ccd7393de1136afcd8ead3
|
File details
Details for the file cve_risk_analyzer-0.1.1-py3-none-any.whl.
File metadata
- Download URL: cve_risk_analyzer-0.1.1-py3-none-any.whl
- Upload date:
- Size: 33.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9cbb549a0966caf96024d7e231f31adfcc3c75153ec0392f575ac682bfcd553
|
|
| MD5 |
ef5cb11270aeb61b03227e2bfe75a210
|
|
| BLAKE2b-256 |
f9e24e783775aaab0780a87b142d2a4d7ff406b51397476946dd5499c8b47cec
|