nvdb-py
A comprehensive Python library and CLI for querying the US National Vulnerability Database (NVD) API 2.0.
Features
- ✨ Full API Coverage: All 5 NVD API 2.0 endpoints (CVE, CPE, CPE Match, Source, CVE History)
- 🚀 Async-First: Built with
httpxfor high-performance async operations - 🔒 Type-Safe: Comprehensive Pydantic models with full type hints
- 🎨 Rich CLI: Beautiful table output, JSON, and YAML formats
- ⚡ Smart Rate Limiting: Automatic rate limiting with support for API keys
- 🔍 30+ Search Parameters: Extensive CVE filtering options
- 📦 Zero Config: Works out of the box, configure only if needed
- 💡 Helpful CLI: Contextual help and examples at every level
Installation
# Using uv (recommended)
uv pip install nvdb-py
# Using pip
pip install nvdb-py
Quick Start
Just Installed? Start Here
# See examples and common commands
nvdb
# Get help for specific commands
nvdb cve --help
nvdb cpe --help
Library Usage
import asyncio
from nvd import NVDClient
async def main():
async with NVDClient() as client:
# Get a specific CVE
cve = await client.cve.get_cve("CVE-2021-44228")
print(f"{cve.id}: {cve.description}")
print(f"CVSS Score: {cve.cvss_v3_score}")
# Search for critical CVEs
async for cve in client.cve.search_cves(
keyword="remote code execution",
cvss_v3_severity="CRITICAL",
has_kev=True
):
print(f"{cve.id} - Score: {cve.cvss_v3_score}")
asyncio.run(main())
CLI Usage
# Run without arguments to see helpful examples
nvdb
# CVE Commands
nvdb cve get CVE-2021-44228 # Get specific CVE
nvdb cve search --keyword "sql injection" --severity HIGH # Search with filters
nvdb cve search --cpe "cpe:2.3:a:apache:log4j:*" # Search by CPE
nvdb cve search --has-kev --severity CRITICAL # CISA KEV catalog
nvdb cve history CVE-2021-44228 # Get change history
# CPE Commands (Product Search)
nvdb cpe search --keyword "windows 10" # Keyword search (recommended)
nvdb cpe search --keyword "apache tomcat" # Search by product name
nvdb cpe search --match-string "cpe:2.3:a:microsoft:*" # CPE format search
nvdb cpe matches --cve CVE-2021-44228 # Get match criteria
# Configuration
nvdb config set-api-key YOUR_API_KEY # Configure API key
nvdb config show # Show current config
# Output Formats
nvdb cve get CVE-2021-44228 --format table # Table (default)
nvdb cve get CVE-2021-44228 --format json # JSON
nvdb cve get CVE-2021-44228 --format yaml # YAML
💡 Tip: Run any command without arguments to see usage examples: -
nvdb cve- Shows CVE command examples -nvdb cpe- Shows CPE command examples -nvdb config- Shows config command examples
## Getting Help
The CLI provides contextual help at every level:
```bash
# Show examples and common commands
$ nvdb
╭───────────────── nvdb - NVD API CLI ─────────────────╮
│ Quick Examples: │
│ nvdb cve get CVE-2021-44228 │
│ nvdb cve search --severity CRITICAL --limit 10 │
│ nvdb cpe search --keyword 'windows 10' │
│ ... │
╰──────────────────────────────────────────────────────╯
# Show standard help
nvdb --help
# Show command-specific examples
nvdb cve # Shows CVE examples
nvdb cpe # Shows CPE examples
# Show detailed command help
nvdb cve search --help # All search options
nvdb cpe search --help # CPE search options
# Missing arguments? Get helpful errors
$ nvdb cve get
Error: Missing argument 'CVE_ID'.
Try 'nvdb cve get --help' for help.
API Key Configuration
Get higher rate limits (50 requests/30 seconds) with an API key from NVD.
# Set via CLI
nvdb config set-api-key YOUR_API_KEY
# Or set environment variable
export NVD_API_KEY=YOUR_API_KEY
# Or pass directly to client
client = NVDClient(api_key="YOUR_API_KEY")
Library API
NVDClient
Main async client for NVD API operations.
async with NVDClient(api_key="optional") as client:
# CVE operations
cve = await client.cve.get_cve("CVE-2021-44228")
async for cve in client.cve.search_cves(...):
print(cve.id)
# CPE operations
cpe = await client.cpe.get_cpe("uuid")
async for cpe in client.cpe.search_cpes(keyword="apache"):
print(cpe.cpeName)
# CPE Match operations
async for match in client.cpematch.search_match_criteria(cve_id="CVE-2021-44228"):
print(match.criteria)
# Source operations
async for source in client.source.list_sources():
print(source.name)
# CVE History operations
history = await client.history.get_cve_history("CVE-2021-44228")
CVE Search Parameters
The CVE endpoint supports 30+ parameters:
async for cve in client.cve.search_cves(
# Identification
cve_id="CVE-2021-44228",
cpe_name="cpe:2.3:a:apache:log4j:*",
# Date ranges (ISO-8601, max 120 days)
pub_start_date="2021-12-01T00:00:00.000",
pub_end_date="2021-12-31T23:59:59.999",
last_mod_start_date="2024-01-01T00:00:00.000",
last_mod_end_date="2024-12-31T23:59:59.999",
# CVSS filtering
cvss_v2_severity="HIGH",
cvss_v3_severity="CRITICAL",
cvss_v3_metrics="AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
# CWE filtering
cwe_id="CWE-79",
# Boolean filters
has_cert_alerts=True,
has_cert_notes=True,
has_kev=True, # CISA Known Exploited Vulnerabilities
has_oval=True,
is_vulnerable=True,
no_rejected=True,
# Keyword search
keyword_search="remote code execution",
keyword_exact_match=False,
# Version filtering (with cpe_name)
version_start="2.0",
version_start_type="including",
version_end="2.17.0",
version_end_type="excluding",
# Pagination
results_per_page=100,
start_index=0,
):
print(f"{cve.id}: {cve.description}")
CPE Search Parameters
Search for products in two ways:
# 1. Keyword search (recommended) - searches titles and metadata
async for cpe in client.cpe.search_cpes(
keyword_search="windows", # Simple text search
keyword_exact_match=False, # Partial match (default)
results_per_page=100
):
print(f"{cpe.cpeName}: {cpe.title}")
# 2. CPE match string - requires CPE 2.3 format
async for cpe in client.cpe.search_cpes(
cpe_match_string="cpe:2.3:a:microsoft:*", # Must be valid CPE format
results_per_page=100
):
print(f"{cpe.cpeName}: {cpe.title}")
# Other CPE operations
cpe = await client.cpe.get_cpe("UUID") # Get by UUID
matches = await client.cpematch.get_cve_match_criteria("CVE-2021-44228") # Get match criteria
Important: cpe_match_string requires valid CPE 2.3 format (e.g., cpe:2.3:a:vendor:product:*). For simple text searches, use keyword_search instead.
CLI Commands
CVE Commands
# Get specific CVE
nvdb cve get CVE-2021-44228
# Search CVEs
nvdb cve search [OPTIONS]
--keyword, -k TEXT Keyword to search
--cpe TEXT CPE name filter
--severity, -s TEXT CVSS v3 severity (LOW, MEDIUM, HIGH, CRITICAL)
--cvss-v2-severity TEXT CVSS v2 severity
--cvss-v3-severity TEXT CVSS v3 severity
--cwe TEXT CWE ID (e.g., CWE-79)
--has-kev Only KEV catalog CVEs
--pub-start TEXT Publication start date
--pub-end TEXT Publication end date
--mod-start TEXT Last modified start date
--mod-end TEXT Last modified end date
--limit, -l INTEGER Max results (default: 20)
--format, -f TEXT Output format (table, json, yaml)
# Get CVE history
nvdb cve history CVE-2021-44228
CPE Commands
# Get specific CPE by UUID
nvdb cpe get <UUID>
# Search CPEs - Two methods:
# 1. Keyword search (recommended for most searches)
nvdb cpe search --keyword "windows" # Search by product name
nvdb cpe search --keyword "apache tomcat" # Search by vendor/product
nvdb cpe search -k "mysql" --limit 10 # Limit results
# 2. CPE match string (requires cpe:2.3 format)
nvdb cpe search --match-string "cpe:2.3:a:microsoft:*" # All Microsoft products
nvdb cpe search -m "cpe:2.3:o:linux:*" # All Linux OS entries
nvdb cpe search -m "cpe:2.3:a:*:soft*" # Products starting with "soft"
# ⚠️ Note: Use --keyword for plain text, --match-string requires CPE format
# Wrong: nvdb cpe search -m "apache" (will fail - not CPE format)
# Right: nvdb cpe search --keyword "apache" (correct for text search)
# Right: nvdb cpe search -m "cpe:2.3:a:apache:*" (correct for CPE format)
# Get CPE match criteria for a CVE
nvdb cpe matches --cve CVE-2021-44228 # Get all match criteria for CVE
nvdb cpe matches --id <UUID> # Get specific match criteria
# Options for all commands:
--limit, -l INTEGER Max results (default: 20)
--format, -f TEXT Output format (table, json, yaml)
--api-key TEXT NVD API key
Config Commands
# Set API key
nvdb config set-api-key YOUR_API_KEY
# Show configuration
nvdb config show
# Clear configuration
nvdb config clear
API Endpoints
| Endpoint | Description | Base URL |
|---|---|---|
| CVE | Vulnerability data | /cves/2.0 |
| CVE History | Change tracking | /cvehistory/2.0 |
| CPE | Product data | /cpes/2.0 |
| CPE Match | Match criteria | /cpematch/2.0 |
| Source | Data sources | /source/2.0 |
Rate Limits
- Without API Key: 5 requests per 30 seconds
- With API Key: 50 requests per 30 seconds
The library automatically handles rate limiting and retries.
Examples
See the examples directory for more usage examples:
basic_usage.py- Simple CVE and CPE queriesadvanced_queries.py- Complex filtering and pagination
Troubleshooting
CPE Search Issues
Problem: nvdb cpe search -m "apache" returns error
Error: Invalid CPE match string: apache. CPE match strings must use the format 'cpe:2.3:...'
Solution: Use --keyword for text search or proper CPE format for --match-string:
# Option 1: Use keyword search (recommended)
nvdb cpe search --keyword "apache"
# Option 2: Use proper CPE format
nvdb cpe search --match-string "cpe:2.3:a:apache:*"
Rate Limiting
Problem: Getting rate limit errors
Solutions:
1. Get an API key for higher limits (50 req/30s vs 5 req/30s):
bash
nvdb config set-api-key YOUR_API_KEY
2. The library automatically retries with backoff - just wait
3. Reduce request frequency in your code
No Results Found
Problem: Search returns no results
Debugging steps:
1. Try broader keywords: --keyword "windows" instead of --keyword "windows 10 pro"
2. Check date ranges aren't too restrictive
3. Verify CVE IDs are correct format: CVE-YYYY-NNNNN
4. For CPE searches, try keyword search first before match strings
API Connectivity
Problem: Connection errors or timeouts
Solutions:
1. Check internet connection
2. Verify NVD API is accessible:
bash
curl -I https://services.nvd.nist.gov/rest/json/cves/2.0
3. Check if you're behind a proxy (set HTTP_PROXY/HTTPS_PROXY env vars)
Development
# Clone repository
git clone https://github.com/nvdb-py/nvdb-py.git
cd nvdb-py
# Install with dev dependencies
uv pip install -e ".[dev]"
# Run tests
pytest
# Format code
black src/
ruff check src/
# Type checking
mypy src/
Requirements
- Python 3.9+
- httpx
- pydantic >= 2.0
- typer
- rich
- pyyaml
- python-dateutil
License
MIT License - see LICENSE file for details.
Credits
Data provided by the National Vulnerability Database (NVD) by NIST.
Links
Note: This project is not affiliated with or endorsed by NIST or the NVD.
