The assumption most security teams operate under: "we check NVD, so we have the vulnerabilities." This assumption was partially true in 2020. By 2026, it's dangerously incomplete. NVD's enrichment backlog, OSV's ecosystem coverage advantages, and GHSA's deep integration with the npm/PyPI/Maven dependency graph mean that any single-source vulnerability intelligence strategy has systematic blind spots.
This is the comprehensive breakdown of what each database is, how it works, where it excels, where it fails, and how to wire them together into a complete picture.
NVD: NIST's National Vulnerability Database
The NVD is the canonical public vulnerability database, operated by NIST and funded by the US government. It's been the default reference point for vulnerability management since 2005. Every CVE ID is rooted in the CVE Program (operated by MITRE), and NVD adds enrichment on top: CVSS scores, CWE classifications, CPE (Common Platform Enumeration) affected product data, and reference links.
How NVD Works
CVEs are first published in the CVE Program's CNA (CVE Numbering Authority) network. MITRE reserves the ID and publishes basic information. NVD analysts then enrich each CVE with CVSS vector strings, CPE applicability statements (which products and versions are affected), and CWE categorization. This enrichment process takes time, historically, days to weeks. Since early 2024, the backlog has extended to months.
NVD Strengths
- Broadest CVE coverage, effectively all public CVEs are eventually in NVD
- CVSS scores for most historical CVEs (pre-2024 backlog)
- CPE-based product matching enables scanner integration
- Free public API (with API key for higher rate limits)
- Authoritative reference, required for FedRAMP and FISMA compliance
NVD Weaknesses
- Enrichment delays, 2024+ CVEs frequently missing CVSS scores for weeks to months
- CPE data quality is inconsistent, many CVEs have wrong or missing affected version ranges
- Poor coverage for package ecosystem vulnerabilities (npm, PyPI, Maven, Go modules)
- No ecosystem-specific package identifier support (no npm package names, no PyPI package names in a machine-consumable format)
OSV: Google's Open Source Vulnerability Database
OSV (Open Source Vulnerabilities) was launched by Google in 2021. It's specifically designed for the open source package ecosystem and uses a structured schema (OSV Schema) that directly encodes affected package names, ecosystem identifiers, and version ranges in a machine-readable format that maps directly to dependency manifests.
How OSV Works
OSV aggregates from multiple upstream sources: GitHub Security Advisories, PyPA (Python), RustSec, Go Vulnerability Database, npm, Packagist, OSS-Fuzz, crates.io, and many others. Each vulnerability record uses the OSV Schema which specifies:
{
"id": "GHSA-xxxx-xxxx-xxxx",
"aliases": ["CVE-2024-XXXXX"],
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "requests"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{"introduced": "0"},
{"fixed": "2.32.0"}
]
}
]
}
]
}
This schema is fundamentally better for software composition analysis (SCA) than NVD's CPE system, because package names and version ranges map directly to what you have in requirements.txt, package.json, or go.mod.
OSV Strengths
- Best ecosystem coverage for open source packages across PyPI, npm, Maven, Go, Rust, Ruby, Packagist, and more
- Machine-readable package name + version range format, enables precise affected version matching without CPE lookups
- Faster publication than NVD for ecosystem-specific vulnerabilities
- Free API at
api.osv.devwith batch query support - Aggregates from GHSA, so GitHub advisory data is included
OSV Weaknesses
- Primarily covers open source software; poor coverage for proprietary commercial products
- No CVSS enrichment, relies on upstream sources for scoring data
- Coverage for some ecosystems (e.g., R packages, Swift) is still maturing
GHSA: GitHub Security Advisories
GitHub Security Advisories is GitHub's native vulnerability advisory system. It has two components: public advisories (the GHSA database, accessible at github.com/advisories) and private advisories for individual repositories. The public GHSA database is a primary source for OSV and is increasingly important for npm, Maven, and Python ecosystem vulnerabilities.
How GHSA Works
Maintainers of GitHub-hosted open source projects can publish security advisories directly through GitHub's interface. GitHub's security team also proactively adds advisories for widely-used packages. GHSA IDs (format: GHSA-xxxx-xxxx-xxxx) are issued by GitHub as a registered CNA.
The key differentiator: GHSA data is published faster than NVD for open source vulnerabilities because it goes directly from the maintainer (who knows the fix) to the advisory, without waiting for NIST analysts to enrich it.
| Attribute | NVD | OSV | GHSA |
|---|---|---|---|
| Coverage scope | All CVEs (commercial + OSS) | Open source packages | GitHub-hosted OSS |
| npm coverage | Partial | Excellent | Excellent |
| PyPI coverage | Partial | Excellent | Good |
| Maven/Java coverage | Partial | Good | Good |
| Commercial product coverage | Excellent | Poor | Poor |
| CVSS scores | Yes (backlog since 2024) | Depends on source | Sometimes |
| Time-to-publish | Days–months (backlog) | Hours–days | Hours–days |
| Machine-readable format | CPE (complex matching) | Package name + semver | Package name + semver |
| Free API | Yes (rate limited) | Yes | Yes (GraphQL) |
How CVEasy AI Uses All Three
CVEasy AI's vulnerability intelligence pipeline queries all three sources for each CVE and merges the results. The logic:
- NVD as the ID namespace: CVE IDs are the canonical identifier. Every CVE starts with an NVD lookup for CVSS scores, CWE, and basic metadata.
- OSV for package ecosystem enrichment: For any CVE affecting a package-manager-distributed component, OSV provides the precise affected version range in a format that maps directly to your SBOM or dependency manifest.
- GHSA as an early-warning system: GHSA frequently publishes advisories before NVD has completed enrichment. For npm, PyPI, and Maven CVEs, GHSA data may arrive 2–3 weeks before NVD enrichment completes.
- Deduplication by CVE alias: All three databases cross-reference CVE IDs. An entry in GHSA with alias
CVE-2024-XXXXXis the same vulnerability as the NVD record, the pipeline merges them, taking the most complete data from each source.
Building a Multi-Source Aggregation Pipeline
import httpx
import asyncio
NVD_API = "https://services.nvd.nist.gov/rest/json/cves/2.0"
OSV_API = "https://api.osv.dev/v1"
GHSA_GRAPHQL = "https://api.github.com/graphql"
async def fetch_nvd(cve_id: str) -> dict:
"""Fetch NVD record with CVSS, CWE, and CPE data."""
async with httpx.AsyncClient() as client:
r = await client.get(f"{NVD_API}?cveId={cve_id}",
headers={"apiKey": NVD_API_KEY})
data = r.json()
vulns = data.get("vulnerabilities", [])
return vulns[0]["cve"] if vulns else {}
async def fetch_osv(cve_id: str) -> dict:
"""Query OSV for package ecosystem data matching this CVE."""
async with httpx.AsyncClient() as client:
r = await client.post(f"{OSV_API}/query",
json={"query": {"id": cve_id}})
return r.json()
async def fetch_ghsa(cve_id: str, gh_token: str) -> dict:
"""Query GHSA via GraphQL for advisories with this CVE alias."""
query = """
query($query: String!) {
securityAdvisories(first: 5, query: $query) {
nodes {
ghsaId
publishedAt
severity
summary
vulnerabilities(first: 10) {
nodes {
package { ecosystem name }
vulnerableVersionRange
firstPatchedVersion { identifier }
}
}
}
}
}"""
async with httpx.AsyncClient() as client:
r = await client.post(GHSA_GRAPHQL,
json={"query": query, "variables": {"query": cve_id}},
headers={"Authorization": f"Bearer {gh_token}"})
return r.json()
async def enrich_cve(cve_id: str, gh_token: str) -> dict:
"""Merge data from all three sources into a unified record."""
nvd, osv, ghsa = await asyncio.gather(
fetch_nvd(cve_id),
fetch_osv(cve_id),
fetch_ghsa(cve_id, gh_token)
)
return {
"id": cve_id,
"cvss": nvd.get("metrics", {}), # From NVD
"cwe": nvd.get("weaknesses", []), # From NVD
"packages": osv.get("vulns", []), # From OSV (precise version ranges)
"advisories": ghsa, # From GHSA (often fastest)
"sources": ["nvd", "osv", "ghsa"]
}