The National Vulnerability Database (NVD) is the U.S. government's repository of vulnerability data. It contains 250,000+ CVEs — and it has a completely free API.
No API key required for basic queries. No authentication. Just HTTP requests.
Why This Matters
A security researcher I know was manually searching NVD's website for vulnerabilities affecting their stack. Copy-pasting CVE details into spreadsheets. It took hours every week.
Then they discovered the NVD API. Now a single script checks their entire dependency list against known vulnerabilities in seconds.
Quick Start — Search Vulnerabilities
Find all critical vulnerabilities from the last 7 days:
\`python
import requests
from datetime import datetime, timedelta
base_url = "https://services.nvd.nist.gov/rest/json/cves/2.0"
Last 7 days of critical CVEs
end = datetime.utcnow()
start = end - timedelta(days=7)
params = {
"pubStartDate": start.strftime("%Y-%m-%dT00:00:00.000"),
"pubEndDate": end.strftime("%Y-%m-%dT23:59:59.999"),
"cvssV3Severity": "CRITICAL"
}
response = requests.get(base_url, params=params)
data = response.json()
print(f"Found {data['totalResults']} critical CVEs this week")
for vuln in data.get("vulnerabilities", [])[:5]:
cve = vuln["cve"]
cve_id = cve["id"]
desc = cve["descriptions"][0]["value"][:100]
print(f"\n{cve_id}: {desc}...")
`\
No key. No signup. Just works.
Search by Keyword
Find vulnerabilities mentioning a specific technology:
\`python
params = {
"keywordSearch": "apache log4j",
"resultsPerPage": 5
}
response = requests.get(base_url, params=params)
data = response.json()
print(f"Total Log4j vulnerabilities: {data['totalResults']}")
for vuln in data["vulnerabilities"]:
cve = vuln["cve"]
metrics = cve.get("metrics", {})
# Get CVSS score if available
score = "N/A"
if "cvssMetricV31" in metrics:
score = metrics["cvssMetricV31"][0]["cvssData"]["baseScore"]
print(f"{cve['id']} | Score: {score} | {cve['descriptions'][0]['value'][:80]}")
`\
Search by CPE (Specific Software)
The real power — find ALL vulnerabilities for a specific product version:
\`python
All vulns for Python 3.11
params = {
"cpeName": "cpe:2.3🅰️python:python:3.11:::::::*",
"resultsPerPage": 20
}
response = requests.get(base_url, params=params)
data = response.json()
print(f"Python 3.11 vulnerabilities: {data['totalResults']}")
for vuln in data["vulnerabilities"]:
cve = vuln["cve"]
print(f" {cve['id']}: {cve['descriptions'][0]['value'][:90]}")
`\
Get Full CVE Details
\`python
cve_id = "CVE-2021-44228" # Log4Shell
response = requests.get(f"{base_url}?cveId={cve_id}")
data = response.json()
cve = data["vulnerabilities"][0]["cve"]
print(f"ID: {cve['id']}")
print(f"Published: {cve['published']}")
print(f"Description: {cve['descriptions'][0]['value'][:200]}")
CVSS v3.1 details
if "cvssMetricV31" in cve.get("metrics", {}):
cvss = cve["metrics"]["cvssMetricV31"][0]["cvssData"]
print(f"CVSS Score: {cvss['baseScore']} ({cvss['baseSeverity']})")
print(f"Attack Vector: {cvss['attackVector']}")
print(f"Attack Complexity: {cvss['attackComplexity']}")
References
for ref in cve.get("references", [])[:3]:
print(f"Reference: {ref['url']}")
`\
Build a Dependency Vulnerability Scanner
Here's something actually useful — scan your requirements.txt:
\`python
import requests
import time
def scan_dependencies(requirements_file):
"""Scan Python dependencies for known vulnerabilities."""
base_url = "https://services.nvd.nist.gov/rest/json/cves/2.0"
with open(requirements_file) as f:
deps = [line.strip().split("==")[0] for line in f
if line.strip() and not line.startswith("#")]
print(f"Scanning {len(deps)} dependencies...\n")
for dep in deps:
params = {
"keywordSearch": dep,
"cvssV3Severity": "HIGH",
"resultsPerPage": 3
}
response = requests.get(base_url, params=params)
if response.status_code == 200:
data = response.json()
count = data["totalResults"]
if count > 0:
print(f"⚠ {dep}: {count} HIGH+ vulnerabilities")
for v in data["vulnerabilities"][:2]:
cve = v["cve"]
print(f" └─ {cve['id']}: {cve['descriptions'][0]['value'][:70]}")
else:
print(f"✓ {dep}: No high-severity CVEs found")
time.sleep(0.6) # Rate limit: ~100 requests per minute
scan_dependencies("requirements.txt")
`\
Rate Limits
- Without API key: 5 requests per 30 seconds
- With API key (free): 50 requests per 30 seconds
- Get a key at: https://nvd.nist.gov/developers/request-an-api-key
Add your key as a header:
\python
headers = {"apiKey": "your-api-key-here"}
response = requests.get(base_url, params=params, headers=headers)
\\
What You Can Build
- Vulnerability scanner for your CI/CD pipeline
- Security dashboard monitoring new CVEs daily
- Dependency checker for open-source projects
- Threat intelligence feed for your security team
- Compliance tool tracking CVEs by severity and vendor
The NVD API gives you the same data that expensive security tools charge thousands for. The difference? This one is free and maintained by NIST.
Building security tools? I create free APIs and developer tools — check my GitHub for more.
Top comments (0)