From 5064f9c297a01b00e4cdba8b47f9dba37a6f3bdf Mon Sep 17 00:00:00 2001 From: Marlon Pina Tojal Date: Fri, 17 May 2024 17:10:00 +0200 Subject: [PATCH 1/6] fix os handling when trivy sets pkgType on properties Signed-off-by: Marlon Pina Tojal --- .../dependencytrack/tasks/scanners/TrivyAnalysisTask.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java index 975c5daf45..6b9b3799fc 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java @@ -259,6 +259,13 @@ public void analyze(final List components) { srcVersion = property.getPropertyValue(); } else if (property.getPropertyName().equals("trivy:SrcRelease")) { srcRelease = property.getPropertyValue(); + } else if (property.getPropertyName().equals("trivy:PkgType")) { + pkgType = property.getPropertyValue(); + String distro = component.getPurl().getQualifiers().get("distro"); + + if (distro != null) { + pkgType += "-" + distro; + } } } @@ -292,6 +299,7 @@ public void analyze(final List components) { pkgs.forEach((key, value) -> { var info = new BlobInfo(); info.setPackageInfos(new PackageInfo[]{value}); + LOGGER.debug("looking for os %s".formatted(key)); if (os.get(key) != null) { info.setOS(os.get(key)); } From d3837aed00278e35192b8615f0757cd06df38055 Mon Sep 17 00:00:00 2001 From: Marlon Pina Tojal Date: Fri, 17 May 2024 18:36:34 +0200 Subject: [PATCH 2/6] add test and only apply package type if distro is not complete Signed-off-by: Marlon Pina Tojal --- .../org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java | 3 ++- .../tasks/scanners/TrivyAnalysisTaskIntegrationTest.java | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java b/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java index 6b9b3799fc..17bb2d21e8 100644 --- a/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java +++ b/src/main/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTask.java @@ -259,8 +259,9 @@ public void analyze(final List components) { srcVersion = property.getPropertyValue(); } else if (property.getPropertyName().equals("trivy:SrcRelease")) { srcRelease = property.getPropertyValue(); - } else if (property.getPropertyName().equals("trivy:PkgType")) { + } else if (!pkgType.contains("-") && property.getPropertyName().equals("trivy:PkgType")) { pkgType = property.getPropertyValue(); + String distro = component.getPurl().getQualifiers().get("distro"); if (distro != null) { diff --git a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java index 51f876b5d3..f10c9534f6 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java @@ -271,6 +271,8 @@ public void testWithPackageWithTrivyProperties() { qm.createComponentProperty(component, "aquasecurity", "trivy:SrcName", "glibc", IConfigProperty.PropertyType.STRING, null); qm.createComponentProperty(component, "aquasecurity", "trivy:SrcVersion", "2.35", IConfigProperty.PropertyType.STRING, null); qm.createComponentProperty(component, "aquasecurity", "trivy:SrcRelease", "0ubuntu3.4", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:PkgType", "ubuntu", IConfigProperty.PropertyType.STRING, null); + final var analysisEvent = new TrivyAnalysisEvent(List.of(osComponent, component)); new TrivyAnalysisTask().inform(analysisEvent); From 8ea602a07766328b258f248f46ad41a7cc5b6cb2 Mon Sep 17 00:00:00 2001 From: Marlon Pina Tojal Date: Fri, 17 May 2024 18:49:45 +0200 Subject: [PATCH 3/6] add test for distro without OS Signed-off-by: Marlon Pina Tojal --- .../TrivyAnalysisTaskIntegrationTest.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java index f10c9534f6..e61986d40a 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java @@ -294,4 +294,94 @@ public void testWithPackageWithTrivyProperties() { }); } + /** + * This test documents the case where Trivy generates a sbom and operative system is not entirely on distro qualifier. + *

+ * Here's an excerpt of the properties included: + *

+     * "properties": [
+     *   {
+     *     "name": "aquasecurity:trivy:LayerDiffID",
+     *    "value": "sha256:7815e55122d4badd6ca652188bb24c925a9c8d710ee712fbb7f3cff29900943c"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:LayerDigest",
+     *     "value": "sha256:bd6651fa9674b8273dfcd61f21610a43fc31ea7b6d0123e7508a89510477deb4"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:PkgID",
+     *     "value": "git@2.43.0-r0"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:PkgType",
+     *     "value": "alpine"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:SrcName",
+     *     "value": "git"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:SrcVersion",
+     *     "value": "2.43.0-r0"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:SrcVersion",
+     *     "value": "2.35"
+     *   }
+     * ]
+     * 
+ *

+ * To reproduce, run: + *

+     * docker run -it --rm aquasec/trivy image --format cyclonedx registry.hub.knime.com/knime/knime-full:r-5.1.2-433
+     * 
+ * + * @see Add support for CycloneDX component properties + * @see Support component properties with Trivy + */ + @Test + public void testWithPackageWithTrivyPropertiesWithDistroWithoutOS() { + final var project = new Project(); + project.setName("acme-app"); + qm.persist(project); + + final var osComponent = new Component(); + osComponent.setProject(project); + osComponent.setName("alpine"); + osComponent.setVersion("3.19.1"); + osComponent.setClassifier(Classifier.OPERATING_SYSTEM); + qm.persist(osComponent); + + final var component = new Component(); + component.setProject(project); + component.setName("git"); + component.setVersion("2.43.0-r0"); + component.setClassifier(Classifier.LIBRARY); + component.setPurl("pkg:apk/alpine/git@2.43.0-r0?arch=x86_64&distro=3.19.1"); + qm.persist(component); + + qm.createComponentProperty(component, "aquasecurity", "trivy:PkgID", "git@2.43.0-r0", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:PkgType", "alpine", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:SrcName", "git", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:SrcVersion", "2.43.0-r0", IConfigProperty.PropertyType.STRING, null); + + final var analysisEvent = new TrivyAnalysisEvent(List.of(osComponent, component)); + new TrivyAnalysisTask().inform(analysisEvent); + + assertThat(qm.getAllVulnerabilities(component)).anySatisfy(vuln -> { + assertThat(vuln.getVulnId()).isEqualTo("CVE-2024-32020"); + assertThat(vuln.getSource()).isEqualTo(Vulnerability.Source.NVD.name()); + + // NB: Can't assert specific values here, as we're testing against + // a moving target. These values may change over time. We do proper + // assertions in TrivyAnalyzerTaskTest. + assertThat(vuln.getTitle()).isBlank(); + assertThat(vuln.getDescription()).isNotBlank(); + assertThat(vuln.getCreated()).isNotNull(); + assertThat(vuln.getPublished()).isNotNull(); + assertThat(vuln.getUpdated()).isNotNull(); + assertThat(vuln.getSeverity()).isNotNull(); + assertThat(vuln.getReferences()).isNotBlank(); + }); + } } From 3c20a89dc47c7cd30305f04406d4d9d0d020f7f3 Mon Sep 17 00:00:00 2001 From: Marlon Pina Tojal Date: Fri, 17 May 2024 18:52:08 +0200 Subject: [PATCH 4/6] wrong reproducible image Signed-off-by: Marlon Pina Tojal --- .../tasks/scanners/TrivyAnalysisTaskIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java index e61986d40a..250461ac6c 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java @@ -333,7 +333,7 @@ public void testWithPackageWithTrivyProperties() { *

* To reproduce, run: *

-     * docker run -it --rm aquasec/trivy image --format cyclonedx registry.hub.knime.com/knime/knime-full:r-5.1.2-433
+     * docker run -it --rm aquasec/trivy image --format cyclonedx aquasec/trivy:0.51.1
      * 
* * @see Add support for CycloneDX component properties From 2791f5a3225bfbfd7867ff00ddc9b998fa5e8028 Mon Sep 17 00:00:00 2001 From: Marlon Pina Tojal Date: Fri, 17 May 2024 19:15:13 +0200 Subject: [PATCH 5/6] change vulnerability id on test Signed-off-by: Marlon Pina Tojal --- .../tasks/scanners/TrivyAnalysisTaskIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java index 250461ac6c..737416c606 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java @@ -369,7 +369,7 @@ public void testWithPackageWithTrivyPropertiesWithDistroWithoutOS() { new TrivyAnalysisTask().inform(analysisEvent); assertThat(qm.getAllVulnerabilities(component)).anySatisfy(vuln -> { - assertThat(vuln.getVulnId()).isEqualTo("CVE-2024-32020"); + assertThat(vuln.getVulnId()).isEqualTo("CVE-2024-32021"); assertThat(vuln.getSource()).isEqualTo(Vulnerability.Source.NVD.name()); // NB: Can't assert specific values here, as we're testing against From f23829be4de01d2a21c34883e0844c555924e3b9 Mon Sep 17 00:00:00 2001 From: Marlon Pina Tojal Date: Fri, 17 May 2024 19:53:54 +0200 Subject: [PATCH 6/6] fix test Signed-off-by: Marlon Pina Tojal --- .../tasks/scanners/TrivyAnalysisTaskIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java index 737416c606..952e229fca 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java @@ -369,13 +369,13 @@ public void testWithPackageWithTrivyPropertiesWithDistroWithoutOS() { new TrivyAnalysisTask().inform(analysisEvent); assertThat(qm.getAllVulnerabilities(component)).anySatisfy(vuln -> { - assertThat(vuln.getVulnId()).isEqualTo("CVE-2024-32021"); + assertThat(vuln.getVulnId()).isEqualTo("CVE-2024-32002"); assertThat(vuln.getSource()).isEqualTo(Vulnerability.Source.NVD.name()); // NB: Can't assert specific values here, as we're testing against // a moving target. These values may change over time. We do proper // assertions in TrivyAnalyzerTaskTest. - assertThat(vuln.getTitle()).isBlank(); + assertThat(vuln.getTitle()).isNotBlank(); assertThat(vuln.getDescription()).isNotBlank(); assertThat(vuln.getCreated()).isNotNull(); assertThat(vuln.getPublished()).isNotNull();