Skip to content

fix: don't drop response field on CycloneDX VEX generation#5737

Open
mmind wants to merge 1 commit intoossf:mainfrom
mmind:vex-response
Open

fix: don't drop response field on CycloneDX VEX generation#5737
mmind wants to merge 1 commit intoossf:mainfrom
mmind:vex-response

Conversation

@mmind
Copy link
Copy Markdown

@mmind mmind commented May 5, 2026

As per
https://cyclonedx.org/docs/1.6/json/#vulnerabilities_items_analysis_response
the response field in CycloneDX is of type array and lib4sbom will silently drop it, if the type does not match.

So add the full response array for CycloneDX files when generating VEX files.

Cc @QSchulz

@mmind
Copy link
Copy Markdown
Author

mmind commented May 5, 2026

Interesting ... the tests generated an array of arrays ...

The issue I had locally was the response field getting parsed from the vex correctly, but missing from the output vex.
With the change above, I then got the expected

        "response": [
          "will_not_fix"
        ]

but somehow it seems there's still something going on.

Will investigate more.

@QSchulz
Copy link
Copy Markdown
Contributor

QSchulz commented May 5, 2026

Yeah so the issue is that VEXParse.parse_vex() processes vulnerabilities differently from the CVE object stores them, so the unit test actually sets response to a list of strings, as it should, but .parse_vex() by way of .__process_vulnerabilities() gets the response from a lib4sbom.VEXParser object via its remediation field, which is a string. Then, .__process_vulnerabilities() sets cve_data["response"] to response which is a string and not a list of strings.

The fix should be:

diff --git a/cve_bin_tool/vex_manager/parse.py b/cve_bin_tool/vex_manager/parse.py
index 150eb917..4ecc379b 100644
--- a/cve_bin_tool/vex_manager/parse.py
+++ b/cve_bin_tool/vex_manager/parse.py
@@ -138,7 +138,7 @@ class VEXParse:
                 cve_data = {
                     "remarks": remarks,
                     "comments": comments if comments else "",
-                    "response": response if response else [],
+                    "response": [response] if response else [],
                 }
                 if justification:
                     cve_data["justification"] = justification.strip()

Yes, technically you can set the remediation field in the VEXParser to an array, but I don't think that's what's intended, see all the logic in .set_remediation() and .validate_remediation() in lib4sbom.

I think we should even change the vulnerability.set_value("remediation", cve.response[0]) you change in this patch to use vulnerability.set_remediation(cve.response[0]) instead.

This does mean that we lose information if there's more than one remediation, but that's a limitation that needs to be dealt with at the level of lib4sbom first.

As per
  https://cyclonedx.org/docs/1.6/json/#vulnerabilities_items_analysis_response
the response field in CycloneDX is of type array and lib4sbom will silently
drop it, if the type does not match.

Currently reading a response from a VEX will not write it back into the
updated VEX because the type does not match.

VEXParse.parse_vex() processes vulnerabilities differently from how the CVE
object stores them, so the unit test actually sets response to a list of
strings, as it should, but .parse_vex() by way of .__process_vulnerabilities()
gets the response from a lib4sbom.VEXParser object via its remediation field,
which is a string.

Then, __process_vulnerabilities() sets cve_data["response"] to response
which is a string and not a list of strings, making lib4sbom drop the field.

So instead put the response element into a 1-element-array

Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
@QSchulz
Copy link
Copy Markdown
Contributor

QSchulz commented May 7, 2026

LGTM

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants