GHSA

A GHSA id — GHSA-xxxx-xxxx-xxxx — names one advisory in the GitHub Advisory Database. It identifies a vulnerability in an open-source package the way a CVE does, but it is assigned by GitHub, and a reviewed GHSA entry carries what a CVE record often lacks: the exact package in npm, PyPI, Maven or another ecosystem, and the version ranges that are affected and patched.

How the id is built

GHSA- plus three groups of four characters, each drawn from 23456789cfghjmpqrvwx — no vowels, no 0/o or 1/l pairs — so an id read aloud or copied from a screenshot survives:

Example What it is
GHSA-3h5v-q93c-6h6q ws request-header DoS, alias CVE-2024-37890
GHSA-j8r2-6x86-q33q requests proxy-header leak, alias CVE-2023-32681 and PYSEC-2023-74
GHSA-grv7-fg5c-xmjg braces uncontrolled resource use, alias CVE-2024-4068

The id is random, not sequential. It says nothing about date, ecosystem or severity — that is in the record.

Reviewed, unreviewed and malware

The database holds three kinds of advisory, and only one of them drives the alerts most people see:

  • Reviewed — curated by GitHub, mapped to a package in a supported ecosystem (npm, PyPI, Maven, NuGet, RubyGems, Go, Composer, crates.io, Pub, Swift, Hex, GitHub Actions) with vulnerable_version_range and patched_versions. Dependabot alerts and npm audit use these.
  • Unreviewed — imported automatically from the NVD, with a CVE and a description but no package mapping. They exist so the database is complete, and they trigger nothing.
  • Malware — packages published to steal or damage, mostly on npm. The fix is always "remove it", never "upgrade".

GHSA and CVE

They are aliases, not competitors. A maintainer can draft a repository security advisory privately, fix the bug in a temporary private fork, and publish — and because GitHub is a CVE Numbering Authority, ask for the CVE in the same form. Once published and reviewed, it lands in the database with both ids. Flaws found by the NVD first arrive the other way round: CVE first, GHSA added on import.

That is why scanners disagree on what to call the same row. npm audit and OSV-Scanner lead with the GHSA id; Trivy and Grype usually lead with the CVE and list the GHSA beside it, or the reverse for advisories that have no CVE. A report that groups by flaw rather than by id avoids counting one bug twice.

Severity

Each reviewed advisory has a label — Critical, High, Moderate or Low — and, usually, a CVSS vector the label comes from. GitHub's label can differ from the NVD's score for the same CVE, because GitHub's reviewers rate the package-level impact. Scanners differ in which one they show; OSV entries carry GitHub's label in database_specific.severity.

Looking one up

# REST
curl -s https://api.github.com/advisories/GHSA-3h5v-q93c-6h6q
# every advisory for a package
curl -s "https://api.github.com/advisories?ecosystem=npm&affects=ws"

Or browse github.com/advisories/GHSA-…. The same records are in the public github/advisory-database repository as OSV JSON files, and on osv.dev.

Where the scan goes next

A scanner hands you a list of GHSA and CVE ids; someone still has to decide which to fix this sprint. Drop the JSON into the free Trivy viewer (Trivy and Grype), the npm audit viewer or the pip-audit / OSV-Scanner viewer: each advisory links to its GitHub page with the aliases beside it. Then publish the report as a link and let the reviewer comment on the advisory itself.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Open the Trivy viewer →

Related