NVD Has a Free API — Search 250,000+ Vulnerabilities Programmatically

Published: (March 24, 2026 at 07:35 PM EDT)
3 min read
Source: Dev.to

Source: Dev.to

Alex Spinov

Alex Spinov

Why This Matters

A security researcher I know was manually searching the NVD website for vulnerabilities affecting their stack, copy‑pasting CVE details into spreadsheets. It took hours every week.

After discovering the NVD API, a single script now checks their entire dependency list against known vulnerabilities in seconds.

Quick Start — Search Vulnerabilities

Find all critical vulnerabilities from the last 7 days

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:

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:

# All vulns for Python 3.11
params = {
    "cpeName": "cpe:2.3:a: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

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 (first three)
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:

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")
        else:
            print(f"❌ {dep}: Request failed ({response.status_code})")

        time.sleep(0.6)  # Rate limit: ~100 requests per minute

# Example usage
scan_dependencies("requirements.txt")

Rate Limits

Access typeRequests per 30 seconds
Without API key5
With API key (free)50

Get a key at:

Add your key as a header:

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.

Security tools? I create free APIs and developer tools — check my GitHub for more.

0 views
Back to Blog

Related posts

Read more »

“공개 취약점(CVE) 늘지만 패치 못해”…레드햇, 기업 OS 보안 전략 제시

공개 보고된 보안 취약점이 늘어나면서 운영체제OS 패치 부담도 커지는 가운데, 레드햇이 기업들이 OS 패치를 더 쉽게 적용할 수 있는 방안을 제시했다. 한국레드햇은 25일 서울 여의도에서 열린 미디어 간담회에서 기업이 OS를 최신 상태로 유지할 수 있도록 지원하는 레드햇의 보안 전략을...