Skip to main content

gcve-sbom-analyzer

CI PyPI Python License: GPL-3.0-or-later

CycloneDX SPDX GCVE OSV Pydantic v2 Typer Ruff

Overview

GCVE-powered SBOM vulnerability analyzer.

gcve-sbom-analyzer reads a Software Bill of Materials (CycloneDX or SPDX), looks up every component in the GCVE vulnerability database, and reports which components are vulnerable. It ranks what to fix first by known exploitation (CISA KEV), exploit likelihood (EPSS) and severity, and its exit code can gate a CI pipeline.

  • Formats: CycloneDX and SPDX 2.x JSON, detected from the file content.
  • Components: language packages (Maven, npm, PyPI, Go, Cargo, NuGet…), Debian, Ubuntu, Alpine, Red Hat, Rocky Linux and AlmaLinux packages, and anything identified by a CPE.
  • Version-aware: only vulnerabilities affecting the component's version are reported.
  • Prioritized: every vulnerability gets a priority tier, from P1 (known exploited) to P4.
  • No account or API key: GCVE and OSV are queried anonymously.

Installation

Requires Python 3.12 or later.

pipx install gcve-sbom-analyzer

or, in a virtual environment:

pip install gcve-sbom-analyzer

Quick start

gcve-sbom-analyzer scan bom.json
 GCVE SBOM Analyzer
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 File    : cyclonedx-java.json
 Format  : cyclonedx
 Scanned : 2026-09-29 20:32:06 UTC

 Components scanned : 4
 Vulnerable         : 4
 Clean              : 0

 Vulnerabilities found : 57
     CRITICAL          : 10
     HIGH              : 36
     MEDIUM            : 10
     LOW               : 1

 P1  Known exploited  : 2
 P2  EPSS ≥ 10%       : 8
 P3  Critical or high : 38
 P4  Other            : 9

────────────────────────────────────────────────────────────────────────────────

 jackson-databind  2.9.10  47 vulnerabilities  ·  CRITICAL
 log4j-api         2.14.1  1 vulnerability     ·  MEDIUM
 log4j-core        2.14.1  7 vulnerabilities   ·  CRITICAL
 spring-core       5.3.17  2 vulnerabilities   ·  HIGH

Results come from live GCVE data, so the counts change over time.

Example SBOMs

The examples/ directory holds small SBOMs of known-vulnerable components to try the tool on:

File Format Components
cyclonedx-java.json CycloneDX 1.5 Maven packages: Log4j 2.14.1 (Log4Shell), Spring, Jackson
spdx-python.json SPDX 2.3 PyPI packages: Django, requests, urllib3, PyYAML, Jinja2
cyclonedx-debian.json CycloneDX 1.5 Debian 11 packages as Trivy records them: OpenSSL, zlib, curl, bash
cyclonedx-cpe.json CycloneDX 1.5 Components identified by CPE only: Apache HTTP Server, nginx
cyclonedx-github.json CycloneDX 1.5 C libraries identified by their GitHub repository, through github and generic PURLs: zlib, Expat, curl, libarchive

Usage

gcve-sbom-analyzer scan [OPTIONS] SBOM_PATH
Option Description
--json Print the report as JSON on stdout.
-d, --detailed List every CVE of each component. Ignored with --json, --prioritized or --top.
-V, --only-vulnerable Only list components with at least one vulnerability. The summary still counts every component.
-p, --prioritized List the most urgent vulnerabilities across all components instead of the components. Ignored with --json.
--top N Number of vulnerabilities to list (default: 10). Implies --prioritized.
--fail-on LEVEL Exit with 1 only for vulnerabilities at least this urgent: kev, p2, p3 or any (default).
-v, --verbose Print each component as it is scanned instead of a progress bar.

Progress and errors go to stderr, so stdout only ever carries the report.

Listing every vulnerability

gcve-sbom-analyzer scan bom.json --detailed --only-vulnerable
 nginx  1.20.0  ·  CVE-2025-23419  MEDIUM    5.3
                ·  CVE-2024-35200  MEDIUM    5.3  unverified
                ·  CVE-2023-44487  HIGH      7.5
                ·  CVE-2022-41742  HIGH      7.1

A vulnerability marked unverified was found for the component's product, but neither its record nor the NVD says whether the component's version is affected. It is kept rather than dropped, and counted like any other.

Ranking what to fix first

gcve-sbom-analyzer scan bom.json --top 5
 #  Tier  CVE             Component                KEV   EPSS  Severity  Score
 1  P1    CVE-2021-44228  log4j-core 2.14.1        ●    99.9%  CRITICAL   10.0
 2  P1    CVE-2021-45046  log4j-core 2.14.1        ●    99.9%  CRITICAL    9.0
 3  P2    CVE-2021-45105  log4j-core 2.14.1             99.9%  MEDIUM      5.9
 4  P2    CVE-2021-44832  log4j-core 2.14.1             97.9%  MEDIUM      6.6
 5  P2    CVE-2020-8840   jackson-databind 2.9.10       26.5%  CRITICAL      —

Each vulnerability falls into the first tier it qualifies for:

Tier Meaning
P1 Known exploited: listed in the CISA KEV catalog.
P2 Likely to be exploited: EPSS probability of 10% or more.
P3 Critical or high severity.
P4 Everything else.

Within a tier, vulnerabilities are sorted by EPSS, then severity, then CVSS score. The EPSS column is the probability of exploitation in the next 30 days, rounded down to 0.1%.

JSON output

gcve-sbom-analyzer scan bom.json --json > report.json

The report holds the summary counts (total_vulnerabilities_count, vulnerabilities_by_severity, vulnerabilities_by_priority, known_exploited_count…) and one entry per component under findings. Each entry lists its vulnerabilities with their CVE id, description, CVSS, severity, references, version_status (affected or unknown), KEV entry, EPSS score and priority tier. The JSON layout may still change before version 1.0.

Exit codes and CI

Code Meaning
0 No vulnerability matching --fail-on was found.
1 At least one vulnerability matching --fail-on was found.
2 The scan could not complete: the SBOM cannot be read, or GCVE or OSV cannot be queried.

--fail-on only changes the exit code, never what is reported. For example, to fail a pipeline on known-exploited vulnerabilities only:

gcve-sbom-analyzer scan bom.json --fail-on kev

How it works

  1. The SBOM is parsed, and each component is identified by its Package URL (PURL) or its CPE.
  2. Packages from a known ecosystem are looked up in OSV, which indexes advisories by package and version. OS packages are looked up by source package and distribution release, the way Debian, Ubuntu, Alpine and Red Hat publish their advisories. Components identified by a GitHub repository, through a github PURL or a generic PURL whose vcs_url or download_url qualifier points at GitHub, are looked up by repository and release tag. Each advisory found is then fetched from GCVE, under its CVE id when it has one.
  3. Other components, and repositories OSV finds nothing for, are searched in GCVE by vendor and product, taken from their CPE or PURL. The affected version ranges of each CVE record are checked against the component's version, and when a record leaves that undecided, the NVD configurations stored in GCVE settle it where they can.
  4. GCVE also supplies each CVE's CISA KEV entry and EPSS score, which set its priority tier.

Every lookup goes to the public db.gcve.eu and api.osv.dev APIs. The scan therefore needs network access, and it sends the names and versions of the SBOM's components to both services.

Known limitations

  • JSON input only: SPDX tag-value, YAML and RDF, and CycloneDX XML are not read yet.
  • SPDX 2.x only: SPDX 3.0 documents are not supported.
  • Slow on large SBOMs: components are looked up one at a time, about 0.2 s each for packages and longer for CPE-identified components with many CVEs. An SBOM of several hundred components takes a few minutes.
  • PURLs with no package ecosystem: generic PURLs that point at no GitHub repository, and other PURL types OSV does not index, fall back to the vendor/product search, which often finds nothing for them unless the component also has a CPE. Repositories hosted elsewhere than GitHub (GitLab, Bitbucket) are not looked up by repository yet.
  • Unknown release tags: OSV reports nothing for a version matching none of a repository's tags, just as for a version no advisory affects, so such a component falls back to the vendor/product search.
  • Red Hat: Red Hat's advisories only cover vulnerabilities it has fixed, so vulnerabilities still unfixed in a RHEL package are not reported.
  • Other distributions: SUSE, Wolfi, Chainguard, Amazon Linux, Oracle Linux and Azure Linux packages are not matched to their advisories. For a supported distribution whose release is missing from the PURL or cannot be mapped, advisories from every release are used and the results are marked unverified. Alpine has no such release-less advisories, so those packages fall back to the vendor/product search.
  • Trivy source packages: the source package names Trivy records in its own properties are read from CycloneDX SBOMs only, not from SPDX ones.

Contributing

Bug reports, ideas and pull requests are welcome: see the contributing guide.

License

GNU General Public License v3.0 or later.

Metadata

Release files for gcve-sbom-analyzer 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gcve-sbom-analyzer 0.1.1
File Size Uploaded
gcve_sbom_analyzer-0.1.1.tar.gz 65.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gcve-sbom-analyzer 0.1.1
File Interpreter ABI Platform
gcve_sbom_analyzer-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 137.8 kB

Release files / gcve_sbom_analyzer-0.1.1.tar.gz

Download URL gcve_sbom_analyzer-0.1.1.tar.gz
Size 65.6 kB
Tags Source
SHA-256 checksum
How to use checksums
4ccb10409cd9c45fe4350582198a54edeade688c2eacae7f3a7029445279e719
BLAKE2b-256 checksum
How to use checksums
0b5133f93360503acf7ed7f4a5ad0e8ed83c0ed4e203be37b817c70c25b04e35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / gcve_sbom_analyzer-0.1.1-py3-none-any.whl

Download URL gcve_sbom_analyzer-0.1.1-py3-none-any.whl
Size 72.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1985a268330d4539eb93dfeeddb1744b3a991298434dbbdea0ba7cee1b28ce96
BLAKE2b-256 checksum
How to use checksums
99c28d05bb67550f25bd3827f8a1ae273f6844133c5a44da4c151ac04115f605
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page