From f2d6b072f7cae5d401cdd4a83386e9f78326715a Mon Sep 17 00:00:00 2001 From: nscuro Date: Sat, 8 Jul 2023 23:55:36 +0200 Subject: [PATCH] Fix VDR export containing non-vulnerable components Fixes #2788 Signed-off-by: nscuro --- .../parser/cyclonedx/CycloneDXExporter.java | 7 ++++++- .../parser/cyclonedx/util/ModelConverter.java | 12 ++++++++---- .../resources/v1/BomResourceTest.java | 13 ------------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java index df743fe770..3595aba055 100644 --- a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java +++ b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java @@ -72,7 +72,12 @@ public Bom create(final Component component) { return create(components, null, null, null); } - private Bom create(final Listcomponents, final List services, final List findings, final Project project) { + private Bom create(List components, final List services, final List findings, final Project project) { + if (Variant.VDR == variant) { + components = components.stream() + .filter(component -> !component.getVulnerabilities().isEmpty()) + .toList(); + } final List cycloneComponents = (Variant.VEX != variant && components != null) ? components.stream().map(component -> ModelConverter.convert(qm, component)).collect(Collectors.toList()) : null; final List cycloneServices = (Variant.VEX != variant && services != null) ? services.stream().map(service -> ModelConverter.convert(qm, service)).collect(Collectors.toList()) : null; final List cycloneVulnerabilities = (findings != null) ? findings.stream().map(finding -> ModelConverter.convert(qm, variant, finding)).collect(Collectors.toList()) : null; diff --git a/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java b/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java index 5cd70e7d33..27bbcdbc38 100644 --- a/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java +++ b/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java @@ -66,6 +66,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; public class ModelConverter { @@ -748,19 +749,19 @@ public static List generateDependencies(final Project project, final final var dependencies = new ArrayList(); final var rootDependency = new Dependency(project.getUuid().toString()); - rootDependency.setDependencies(convertDirectDependencies(project.getDirectDependencies())); + rootDependency.setDependencies(convertDirectDependencies(project.getDirectDependencies(), components)); dependencies.add(rootDependency); for (final Component component : components) { final var dependency = new Dependency(component.getUuid().toString()); - dependency.setDependencies(convertDirectDependencies(component.getDirectDependencies())); + dependency.setDependencies(convertDirectDependencies(component.getDirectDependencies(), components)); dependencies.add(dependency); } return dependencies; } - private static List convertDirectDependencies(final String directDependenciesRaw) { + private static List convertDirectDependencies(final String directDependenciesRaw, final List components) { if (directDependenciesRaw == null || directDependenciesRaw.isBlank()) { return Collections.emptyList(); } @@ -772,7 +773,10 @@ private static List convertDirectDependencies(final String directDep if (directDependenciesJson instanceof final JsonArray directDependenciesJsonArray) { for (final JsonValue directDependency : directDependenciesJsonArray) { if (directDependency instanceof final JsonObject directDependencyObject) { - dependencies.add(new Dependency(directDependencyObject.getString("uuid"))); + final String componentUuid = directDependencyObject.getString("uuid", null); + if (componentUuid != null && components.stream().map(Component::getUuid).map(UUID::toString).anyMatch(componentUuid::equals)) { + dependencies.add(new Dependency(directDependencyObject.getString("uuid"))); + } } } } diff --git a/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java index 7a0a80fc0b..d528724646 100644 --- a/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java @@ -531,12 +531,6 @@ public void exportProjectAsCycloneDxVdrTest() { ] }, "components": [ - { - "type": "library", - "bom-ref": "${json-unit.matches:componentWithoutVulnUuid}", - "name": "acme-lib-a", - "version": "1.0.0" - }, { "type": "library", "bom-ref": "${json-unit.matches:componentWithVulnUuid}", @@ -554,16 +548,9 @@ public void exportProjectAsCycloneDxVdrTest() { { "ref": "${json-unit.matches:projectUuid}", "dependsOn": [ - "${json-unit.matches:componentWithoutVulnUuid}", "${json-unit.matches:componentWithVulnAndAnalysisUuid}" ] }, - { - "ref": "${json-unit.matches:componentWithoutVulnUuid}", - "dependsOn": [ - "${json-unit.matches:componentWithVulnUuid}" - ] - }, { "ref": "${json-unit.matches:componentWithVulnUuid}", "dependsOn": []