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[].events is the part that matters. Read the events in order: introduced 2.3.0, fixed 2.31.0 means >=2.3.0 <2.31.0. introduced "0" means from the first release. last_affected is an inclusive upper bound, used when nothing is fixed yet.
  • Range type sets the ordering: ECOSYSTEM uses the package manager's own rules (PEP 440 for PyPI, so 2.10 sorts after 2.9), SEMVER uses semver, GIT uses commit history.
  • severity holds a CVSS vector string, not a number. GitHub-sourced entries add a label in database_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.

Open the pip-audit viewer →

Related