Fix project-scoped affects and duplicate bom-refs in VEX/VDR export#6555
Open
contain-security wants to merge 1 commit into
Open
Fix project-scoped affects and duplicate bom-refs in VEX/VDR export#6555contain-security wants to merge 1 commit into
contain-security wants to merge 1 commit into
Conversation
CycloneDX VEX/VDR exports set every affects[].ref to the project UUID and emitted one vulnerability entry per finding, all sharing the bare vulnerability UUID as their bom-ref. That violated the CycloneDX rule that every bom-ref is unique within a BOM, and on re-import the project-level affects broadcast one component's analysis to every component sharing the vulnerability. Findings are now grouped by (vulnerability, analysis fingerprint) per CycloneDX VEX Use-Case 13: one entry per group, affects[] carrying the sorted union of affected component bom-refs. When a vulnerability splits across analyses, each entry's bom-ref gets a deterministic suffix (<uuid>/0, /1) so uniqueness holds. The Variant enum now carries capability flags in place of scattered switch/== checks. ModelConverter.analysisFingerprint is pinned to its positional, enum-name contract, with a round-trip regression proving an exported VEX re-imports its analysis onto the analysed component only. Fixes DependencyTrack#6016 Fixes DependencyTrack#6017 Signed-off-by: Contain.Security <contain.security@pacificdigitalconsulting.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 23 |
| Duplication | -50 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
CycloneDX VEX and VDR exports were producing documents that violated the
CycloneDX
bom-refuniqueness rule and could not be reliably round-trippedback into Dependency-Track:
affects[].refpointed at the project UUID instead of the affectedcomponent(s). On re-import, the importer applied one component's analysis
to every component sharing the vulnerability.
vulnerabilities[]entry was emitted per finding, and all entries for thesame vulnerability reused the bare vulnerability UUID as their
bom-ref. Aproject with several components affected by the same CVE therefore emitted
duplicate
bom-refvalues, which the CycloneDX spec forbids ("Every bom-refMUST be unique within the BOM").
This PR groups findings by
(vulnerability, analysis fingerprint)and emits oneentry per group, with
affects[]carrying the sorted union of the affectedcomponent
bom-refs — the pattern documented as CycloneDX VEX Use-Case 13. Whena single vulnerability legitimately splits across distinct analyses, each entry's
bom-refgets a deterministic numeric suffix (<uuid>/0,<uuid>/1, …) souniqueness holds; the common single-group case keeps the bare vulnerability UUID,
matching the existing reference exports.
Addressed Issue
Fixes #6016
Fixes #6017
Additional Details
Why group by analysis fingerprint. VDR/VEX emit per-component analysis. Two
components affected by the same vulnerability may carry different analyses
(e.g. one
RESOLVED, one untriaged), so they cannot collapse into a single entrywithout losing analysis fidelity — hence grouping by
(vulnerability, analysisFingerprint). Variants that do not emit analysis(
INVENTORY_WITH_VULNERABILITIES) collapse all findings for a vulnerability intoone group.
Fingerprint contract.
analysisFingerprintis a positional,Enum.name()-based serialisation of(state, justification, response, details)joined by U+001F, so absent fields cannot collide with present ones. It is pinned
by
ModelConverterTest.bom-ref suffixing. The
<uuid>/Nsuffix is applied only when onevulnerability produces more than one group; singletons keep the bare UUID for
backward-compatible output. The
/separator isolates the suffix from the UUIDalphabet so a singleton UUID can never prefix-collide with a multi-group entry.
Variant refactor. The
Variantenum was changed from scatteredswitch/==checks to explicit capability flags (includesAnalysis(),emitsFindings(),filtersToVulnerableComponents(), …). This is incidental tothe fix; happy to split it into a separate commit/PR if you'd prefer to keep the
fix minimal.
Performance. Per-
(component, vulnerability)analysis lookups are memoisedacross the group-key and group-conversion passes, so this does not add queries
relative to the previous per-finding path — it reduces them.
Tests.
CycloneDXVexImporterTest#shouldApplyExportedVexAnalysisOnlyToAnalyzedComponent— round-trip regression: exports a VEX and re-imports it, asserting the analysis
lands only on the analysed component.
CycloneDxBomAssertions.assertBomRefsUnique— reusable cross-documentbom-refuniqueness assertion, applied to the VEX/VDR/BOM resource tests(JSON Schema cannot express cross-property uniqueness).
ModelConverterTest— pins the fingerprint serialisation contract.ADR. I don't believe this meets the ADR bar — it's a spec-conformance bug
fix, not a new API version, auth model, schema change, or cross-cutting
convention. It does change the shape of an externally-consumed export and its
re-import semantics, so flagging it explicitly for your judgement.
Docs. The previous output was spec-violating, so I don't think the docs
describe the old
affects/bom-refbehaviour specifically. Happy to open acompanion PR against
DependencyTrack/docsif the new behaviour warrants a note.Checklist
This PR implements an enhancement, and I have provided tests to verify that it works as intendedThis PR introduces changes to the database model, and I have updated themigration changelogaccordinglydocs/adr/