Safeguard
Vulnerability Analysis•

Which Comes First, the NVD Record or the GitHub Advisory? We Measured

For 1,089 CVEs matched to a GitHub advisory, 77.1% had an NVD publish time earlier than the advisory's. The median gap was 6.9 hours, and 7.4 days for non-GitHub CNAs.

Safeguard Security Team
3 min read

We matched 1,089 GitHub-reviewed advisories to their CVE records in the NVD API, for CVEs published 1 September to 16 October 2026. In 840 of them (77.1%), the NVD record's publish time was earlier than the advisory's published time. The median gap was 6.9 hours, with the NVD record first.

If your process waits for a GHSA to learn about a CVE, this is the delay you may be adding.

How we counted

Two public sources, both downloaded on 18 October 2026. The first is NVD API 2.0, filtered on publication date (24,141 records for the window). The second is the OSV bulk zips for npm, PyPI, Go, Maven, NuGet, RubyGems, crates.io, Packagist, Pub and Hex, filtered to GHSA- records published in the same window and not withdrawn (1,522 unique advisories).

curl -sS "https://services.nvd.nist.gov/rest/json/cves/2.0?pubStartDate=2026-09-01T00:00:00.000Z&pubEndDate=2026-10-16T23:59:59.999Z&resultsPerPage=2000&startIndex=0"
# repeat with startIndex=2000, 4000 ... until startIndex passes totalResults; sleep between calls
# nvd: dict of CVE id -> NVD record; ghsa: list of OSV GHSA records
from datetime import datetime
t = lambda s: datetime.fromisoformat(s.replace("Z", "+00:00")).replace(tzinfo=None)
hours = []
for g in ghsa:
    cves = [a for a in g.get("aliases", []) if a.startswith("CVE-")]
    if cves and cves[0] in nvd:
        hours.append((t(nvd[cves[0]]["published"]) - t(g["published"])).total_seconds() / 3600)

Negative means the NVD record came first. We used each advisory's first CVE alias. 101 advisories have no CVE alias, and 332 have a CVE that NVD did not publish inside the window, so they are not matched.

What's affected

OrderCVEsShare
NVD record 7 or more days before the GHSA13112.0%
NVD 1 to 7 days before27725.4%
NVD 0 to 24 hours before43239.7%
GHSA 0 to 24 hours before NVD18216.7%
GHSA 1 to 7 days before NVD403.7%
GHSA 7 or more days before NVD272.5%
Total matched1,089

The split by who assigned the CVE matters more than the ecosystem:

CNAMatchedNVD firstMedian gap
GitHub (security-advisories@github.com)89475.0%NVD 4.7 hours earlier
All other CNAs19587.2%NVD 177.4 hours (7.4 days) earlier

The other CNAs are mostly VulnCheck (102) and Microsoft (43). The timestamps are as the two databases report them, and we did not investigate why GitHub's published trails NVD's.

What to do now

  1. Don't use the GHSA as your only trigger. Subscribe to a CVE or NVD feed as well.
  2. Match on CVE ID, not on advisory ID. Many CVEs show up in NVD before an advisory exists.
  3. Record both timestamps in your tracker so you can measure your own detection delay.

Quick check

In what share of matched CVEs did NVD publish before the GitHub advisory?

840 of 1,089, or 77.1%.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.