OSV
OSV — Open Source Vulnerability — is an open JSON format for describing a vulnerability in an open-source package, and the database at osv.dev that collects advisories in that format. One entry says which package in which ecosystem is affected, which version ranges, what fixes it, and what other ids the same flaw is known by. Google launched it in 2021; the schema is now developed in the open under the OpenSSF.
Why one flaw has three names
Advisories are filed by many databases, each with its own id prefix:
| Prefix | Source |
|---|---|
GHSA- |
GitHub Advisory Database (every ecosystem) |
PYSEC- |
PyPA advisory database (Python) |
GO- |
Go vulnerability database |
RUSTSEC- |
RustSec (Rust crates) |
MAL- |
Malicious package reports (OpenSSF) |
CVE- |
The CVE program — an alias, not an OSV source |
The Requests proxy-header leak is GHSA-j8r2-6x86-q33q, PYSEC-2023-74
and CVE-2023-32681 at once. Each entry lists the others in aliases, and
OSV-Scanner folds them into one group so a report counts the flaw once
instead of three times. related is different: similar, not the same.
What an entry contains
{
"id": "GHSA-j8r2-6x86-q33q",
"aliases": ["CVE-2023-32681", "PYSEC-2023-74"],
"summary": "Unintended leak of Proxy-Authorization header in requests",
"severity": [{ "type": "CVSS_V3", "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:N/A:N" }],
"affected": [
{
"package": { "ecosystem": "PyPI", "name": "requests" },
"ranges": [
{ "type": "ECOSYSTEM", "events": [{ "introduced": "2.3.0" }, { "fixed": "2.31.0" }] }
]
}
],
"database_specific": { "severity": "MODERATE", "cwe_ids": ["CWE-200"] }
}
affected[].ranges[].eventsis the part that matters. Read the events in order:introduced 2.3.0,fixed 2.31.0means>=2.3.0 <2.31.0.introduced "0"means from the first release.last_affectedis an inclusive upper bound, used when nothing is fixed yet.- Range
typesets the ordering:ECOSYSTEMuses the package manager's own rules (PEP 440 for PyPI, so2.10sorts after2.9),SEMVERuses semver,GITuses commit history. severityholds a CVSS vector string, not a number. GitHub-sourced entries add a label indatabase_specific.severity.
Querying it
curl -s -d '{"package":{"name":"requests","ecosystem":"PyPI"},"version":"2.25.0"}' \
https://api.osv.dev/v1/query
Most people never call the API directly. They run a scanner:
- OSV-Scanner reads lockfiles from PyPI, npm, Go, Maven, crates.io, RubyGems, Packagist, NuGet and more, plus container images and SBOMs.
- pip-audit queries the PyPI vulnerability API by default (PYSEC data)
or OSV directly with
-s osv. - Renovate can open upgrade PRs from OSV alerts.
Where the output goes
A scan produces a list of advisories; the work is deciding what to do about
each one, and that decision usually belongs to someone who won't read CI
logs. Drop osv-scanner --format json or pip-audit -f json into the free
pip-audit / OSV-Scanner viewer and it lists each
group once under its GHSA id with the aliases, range and fixed version —
then publish it as a link and comment on the advisory itself.
Try it
Comma is free — unlimited reports, unlimited commenters, unlimited revision history.