gcve-sbom-analyzer
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
- The SBOM is parsed, and each component is identified by its Package URL (PURL) or its CPE.
- 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
githubPURL or agenericPURL whosevcs_urlordownload_urlqualifier 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. - 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.
- 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:
genericPURLs 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
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)
| File | Size | Uploaded | |
|---|---|---|---|
| gcve_sbom_analyzer-0.1.1.tar.gz | 65.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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