Skip to content

fix: generated VEX outputs contain invalid CSAF fields and unresolved CycloneDX references #5846

Description

@AenganZ

Description

CVE Binary Tool currently generates VEX documents for --vex-type csaf, cyclonedx, and openvex, but the generated CSAF and CycloneDX outputs contain structural/spec-conformance issues.

This was reproduced with the same target image, nginx:1.21.6 (linux/arm64, Debian 11.3). This report only concerns generated VEX document structure and identifier/reference integrity. It does not assess whether the generated VEX statuses are factually correct.

CSAF: empty document.title and threats[].details

The generated CSAF VEX contains 348 vulnerability entries. In the generated file:

  • /document/title is an empty string.
  • All 348 /vulnerabilities[]/threats[]/details values are empty strings.

I checked the CVE Binary Tool VEX documentation and the documented Limitations section, but I did not find a note saying that empty CSAF title or empty CSAF threats[].details values are intentional or expected in generated CSAF output:
https://cve-bin-tool.readthedocs.io/en/stable/triaging_process.html#limitations

Could you confirm whether these empty values are intentional?

If they are not intentional, would it make sense to handle them differently for CSAF output?

  • For document.title, CSAF requires a non-empty title. Since CVE Binary Tool already asks users to provide VEX metadata such as --product, --vendor, and --release, one option may be to add a CSAF-specific title input option, or derive a default title from the existing product/release/vendor values.
  • For threats[].details, if CVE Binary Tool does not yet have a user-provided comment or threat detail, it may be better to omit the optional threats entry rather than serialize details as an empty string.

CSAF: duplicate CVEs

The same CSAF output contains 348 vulnerability objects but only 336 distinct CVEs. 12 CVEs appear twice:

CVE-2021-22876, CVE-2021-22890, CVE-2021-22924, CVE-2021-22945, CVE-2023-27535, CVE-2023-27536, CVE-2023-27538, CVE-2023-38545, CVE-2023-38546, CVE-2023-44487, CVE-2024-7264, CVE-2025-0725

CSAF 2.0 includes a mandatory test for "Multiple Use of Same CVE":
https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html#6123-multiple-use-of-same-cve

These duplicate entries appear to describe the same CVE/product/status relationship and should likely be merged into one vulnerability item per CVE.

CycloneDX: affects[].ref points to undefined local refs

The generated CycloneDX VEX contains:

  • components: 0
  • vulnerabilities: 348
  • affects[].ref: 348 values
  • unique affects[].ref: 31 values

Every vulnerability has an affects[].ref such as:

  • urn:cbt:1/gnu#coreutils:8.32
  • urn:cbt:1/kernel#util-linux:2.36.1
  • urn:cbt:1/gnu#glibc:2.31

However, there are no corresponding components[] entries with matching bom-ref values. Therefore all 348 affects[].ref values point to undefined local BOM references.

This appears related to #5723, but the issue is still reproducible in the current generated CycloneDX VEX output.

Non-blocking OpenVEX observation

The generated OpenVEX document did not fail schema validation in this test.

One minor interoperability observation was found:

  • document and statement timestamps are generated without a timezone/UTC offset, e.g. 2026-07-20T15:54:29.

OpenVEX requires document timestamps and treats statement time as important for VEX interpretation; the specification examples use timestamps with explicit offsets, e.g. 2023-01-08T18:02:03.647787998-06:00.

This is a recommendation only and is not required to resolve the CSAF/CycloneDX issues above.

To reproduce

Steps to reproduce the behaviour:

  1. Prepare a local root filesystem from nginx:1.21.6 for linux/arm64.
  2. Generate VEX outputs:
  • cve-bin-tool <nginx-rootfs-dir> --product nginx --vendor nginx --release 1.21.6 --vex-type csaf --vex-output <output-dir>/cbt_self_csaf.json
  • cve-bin-tool <nginx-rootfs-dir> --product nginx --vendor nginx --release 1.21.6 --vex-type cyclonedx --vex-output <output-dir>/cbt_self_cdx.json
  • cve-bin-tool <nginx-rootfs-dir> --product nginx --vendor nginx --release 1.21.6 --vex-type openvex --vex-output <output-dir>/cbt_self_openvex.json

Expected behaviour:

  • Generated CSAF VEX should pass CSAF 2.0 schema validation, unless the empty title and threats[].details values are intentional and documented limitations.
  • Generated CSAF VEX should not repeat the same CVE across multiple vulnerability items.
  • Generated CycloneDX VEX should not contain affects[].ref values that point to undefined local bom-ref values.

Actual behaviour:

  • CSAF output has an empty /document/title; I could not find this described as an intentional limitation.
  • CSAF output has 348 empty /vulnerabilities[]/threats[]/details values; I could not find this described as an intentional limitation.
  • CSAF output repeats 12 CVEs.
  • CycloneDX output has 348 unresolved affects[].ref references.

Version/platform info

Version of CVE-bin-tool:

  • v3.4.1rc0-575-ged85ae6e
  • commit: ed85ae6ee780112d41c5da066eba81e70ec10a29

Installed from pypi or github?

  • GitHub checkout

Operating system:

  • macOS / Darwin arm64

Python version:

  • Python 3.12.7

Running in any particular CI environment?

  • No

Anything else?

The generated CSAF, CycloneDX, and OpenVEX files are attached.

This report is about generated VEX document structure, identifier/reference integrity, and conformance to the documented VEX formats. It does not assess whether the generated VEX statuses such as under_investigation, affected, not_affected, or fixed are factually correct for the scanned image.

cbt_self_cdx_sanitized.json
cbt_self_csaf_sanitized.json
cbt_self_openvex_sanitized.json

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions