sbom-cve-check is a lightweight, standalone tool that analyzes a Software Bill of Materials (SBOM) against public vulnerability databases and reports which software components are affected by known vulnerabilities. It supports SBOMs in both SPDX v2.2 and SPDX v3.0 formats. It checks them against the NVD and CVE List vulnerability databases. Results can be exported in several formats, including SPDX v3.0 and the Yocto Project cve-check manifest format. It is developed and maintained by Bootlin engineer Benjamin Robin.
We are happy to announce the release of sbom-cve-check 1.4.0. This release adds an OpenVEX exporter, substantially improves the analysis of Linux kernel CVE version ranges, and makes version parsing and annotation handling more robust. As usual, the new version is available from PyPI and the release page, and the complete list of changes is in the changelog.
OpenVEX export
The most visible new feature is the openvex export type, contributed by Andrey Zhizhikin. It generates an OpenVEX v0.2.0 document describing the VEX assessments computed by sbom-cve-check:
sbom-cve-check \ --sbom-path image.spdx.json \ --export-type openvex \ --export-path image.openvex.json \ --export-author "ACME Security Team"
For each component in the SBOM and each applicable vulnerability, the exporter adds a VEX statement containing:
- the vulnerability identifier and description, with a link to the NVD detail page for CVE identifiers;
- the products the statement applies to, using the component’s CPE 2.3 and PURL identifiers, with the version used for the analysis;
- the VEX status and status notes, including the patches fixing a vulnerability for
fixedassessments, the action statement foraffectedassessments, and the justification or impact statement fornot_affectedassessments.
Components without an identifier are skipped, since an OpenVEX product must be identifiable, and identical statements are only emitted once. The document identifier is derived from a hash of its content, so the output remains reproducible, as with the other exporters.
The new --export-author option sets the author recorded in exported documents that carry metadata.
A minimal exported document looks like this:
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-...",
"author": "SBOM CVE Checker Generator",
"role": "Document Creator",
"timestamp": "2026-11-01T17:03:30+00:00",
"version": 1,
"tooling": "sbom-cve-check/1.4.0",
"statements": [
{
"vulnerability": {
"name": "CVE-2026-12345",
"@id": "https://nvd.nist.gov/vuln/detail/CVE-2026-12345",
"description": "The cleanup of tempfile.TemporaryDirectory is vulnerable to a race condition..."
},
"products": [
{
"identifiers": {
"cpe23": "cpe:2.3:*:*:cpython:3.14.7:*:*:*:*:*:*:*"
}
},
{
"identifiers": {
"cpe23": "cpe:2.3:*:python:python:3.14.7:*:*:*:*:*:*:*"
}
},
{
"identifiers": {
"purl": "pkg:yocto/core/python3@3.14.7"
}
}
],
"status": "affected",
"version": 1,
"timestamp": "2026-11-01T17:03:30+00:00",
"status_notes": "version-in-range",
"action_statement": "May need backporting (fixed from 3.14.9)",
"action_statement_timestamp": "2026-11-01T17:03:30+00:00"
}
]
}
More details are available in the export documentation.
More accurate Linux kernel CVE assessments
Linux kernel CVEs are particularly tricky to assess. The kernel.org CNA describes vulnerabilities against mainline and stable branches. A naive numeric comparison of versions can therefore produce both false positives and false negatives.
This release reworks the handling of kernel version ranges (#43) so that the tested version is first checked against the kernel branch described by the range. This makes the analysis aware of the distinction between mainline versions such as 6.12 and stable versions such as 6.12.34, and allows ranges to be accepted or ignored depending on whether the component version really belongs to the branch they describe.
The VEX assessment logic has also been improved to:
- detect the first vulnerable version in the mainline branch, which helps determine that a component predates the introduction of a vulnerability;
- use the kernel CNA’s default status when no version range matches the component’s branch;
- ignore versions carrying a distribution suffix when computing the highest fixed version.
The resulting reports are more useful for real-world kernels, with clearer Needs backporting and May need backporting status notes and fewer misleading assessments. The updated logic is described in the design documentation.
More robust version parsing and comparison
Public vulnerability databases contain a wide variety of version formats, and embedded products add their own conventions on top. Version parsing and comparison received a lot of attention in this release, with support added or fixed for formats such as:
0.9.8zf,0.9~rc5, and7.10.6-revision22;- versions with a two-digit epoch;
- Ubuntu-style suffixes, including suffixes without a number, such as
1.1.9-1ubuntu; - version ranges whose lower bound contains a wildcard, such as
1.2.*; - versions with alphabetical segments, with natural ordering so that
1.2.3abis greater than1.2.3z; - unparseable versions, which can now still be compared for equality;
- git revisions embedded in version strings, with improved detection.
Build metadata is ignored when comparing versions, in line with the semantic versioning specification: 1.25.0 and 1.25.0+4f85853f64 compare as equal. These changes reduce the risk of a CVE being missed or incorrectly reported because a version string was not understood.
Better annotation and VEX handling
Several improvements make it easier to combine vulnerability information from multiple sources:
- multiple simple annotation entries can now describe the same CVE identifier, instead of only the last one being retained;
- multiple OpenVEX statements for the same CVE identifier are supported;
- SPDX 2 annotations can carry multiple package versions;
- OpenVEX annotation globs may point to a directory, simplifying the configuration of annotation databases.
The generation of assessments from Yocto Project VEX manifests was also fixed. For an Unpatched status, the description is now used as the action statement rather than being stored in the status notes. For an Ignored status, the justification configured in Yocto’s cve-check-map.conf is used, and the justification present in the description field is extracted.
Smaller improvements
This release also includes a number of smaller changes:
- the products database now accepts mappings with a wildcard vendor, and a new
crowcpp:crowentry was added; - exported datetime fields may now include microseconds, as input datetimes are no longer truncated;
- error reporting is clearer when extracting a compressed SPDX 2 SBOM, for example when
tarorzstdis missing (#39); - command-line input paths are validated earlier, so a missing file or directory is reported immediately;
- the project documentation now references the Bootlin security page, and the Ruff and Ty configurations were updated to their latest versions.
Upgrading
sbom-cve-check 1.4.0 can be installed or upgraded with:
pip install --upgrade "sbom-cve-check[extra]"
The extra variant pulls in optional dependencies for YAML annotation support, shell completion, and TOML configuration generation. Zstandard compression can be enabled separately with the zstd or zstandard extras. As always, we recommend installing the tool in a Python virtual environment.
We would like to thank Andrey Zhizhikin for their first contribution to the project, as well as all users who reported issues and provided feedback. If you use sbom-cve-check in your products or CI pipelines, we are always interested in hearing about your experience and your suggestions for future releases.
