From 306e68bc7c6d7fddbee74b10692e696d23f10947 Mon Sep 17 00:00:00 2001 From: nscuro Date: Thu, 12 Dec 2024 13:47:36 +0100 Subject: [PATCH] Fix component de-duplication potentially causing duplicate dependency graph entries Fixes #4455 Signed-off-by: nscuro --- .../tasks/BomUploadProcessingTask.java | 10 + .../tasks/BomUploadProcessingTaskTest.java | 82 +- src/test/resources/unit/bom-issue4455.json | 1168 +++++++++++++++++ 3 files changed, 1248 insertions(+), 12 deletions(-) create mode 100644 src/test/resources/unit/bom-issue4455.json diff --git a/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java b/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java index d7bf193b9d..ec1d3dc41d 100644 --- a/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java +++ b/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java @@ -654,9 +654,19 @@ private String resolveDirectDependenciesJson( } final var jsonDependencies = new JSONArray(); + final var directDependencyIdentitiesSeen = new HashSet(); for (final String directDependencyBomRef : directDependencyBomRefs) { final ComponentIdentity directDependencyIdentity = identitiesByBomRef.get(directDependencyBomRef); if (directDependencyIdentity != null) { + if (!directDependencyIdentitiesSeen.add(directDependencyIdentity)) { + // It's possible that multiple direct dependencies of a project or component + // fall victim to de-duplication. In that case, we can ironically end up with + // duplicate component identities (i.e. duplicate BOM refs). + LOGGER.debug("Omitting duplicate direct dependency %s for BOM ref %s" + .formatted(directDependencyBomRef, dependencyBomRef)); + continue; + } + jsonDependencies.put(directDependencyIdentity.toJSON()); } else { LOGGER.warn(""" diff --git a/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java b/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java index 100241138d..852026ffab 100644 --- a/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java @@ -50,14 +50,21 @@ import org.dependencytrack.parser.spdx.json.SpdxLicenseDetailParser; import org.dependencytrack.search.document.ComponentDocument; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonReader; import javax.jdo.JDOObjectNotFoundException; +import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -1440,23 +1447,74 @@ public void informIssue3981Test() { } @Test - public void informIssue3936Test() throws Exception{ + public void informIssue3936Test() throws Exception { final Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false); List boms = new ArrayList<>(Arrays.asList("/unit/bom-issue3936-authors.json", "/unit/bom-issue3936-author.json", "/unit/bom-issue3936-both.json")); - for(String bom : boms){ - final var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), - resourceToByteArray(bom)); - new BomUploadProcessingTask().inform(bomUploadEvent); - awaitBomProcessedNotification(bomUploadEvent); - - assertThat(qm.getAllComponents(project)).isNotEmpty(); - Component component = qm.getAllComponents().getFirst(); - assertThat(component.getAuthor()).isEqualTo("Joane Doe et al."); - assertThat(component.getAuthors().get(0).getName()).isEqualTo("Joane Doe et al."); - assertThat(component.getAuthors().size()).isEqualTo(1); + for (String bom : boms) { + final var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), + resourceToByteArray(bom)); + new BomUploadProcessingTask().inform(bomUploadEvent); + awaitBomProcessedNotification(bomUploadEvent); + + assertThat(qm.getAllComponents(project)).isNotEmpty(); + Component component = qm.getAllComponents().getFirst(); + assertThat(component.getAuthor()).isEqualTo("Joane Doe et al."); + assertThat(component.getAuthors().get(0).getName()).isEqualTo("Joane Doe et al."); + assertThat(component.getAuthors().size()).isEqualTo(1); } } + @Test + public void informIssue4455Test() throws Exception { + final var project = new Project(); + project.setName("acme-app"); + project.setVersion("1.2.3"); + qm.persist(project); + + var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), + resourceToByteArray("/unit/bom-issue4455.json")); + new BomUploadProcessingTask().inform(bomUploadEvent); + awaitBomProcessedNotification(bomUploadEvent); + + qm.getPersistenceManager().refresh(project); + assertThat(project.getDirectDependencies()).satisfies(directDependenciesJson -> { + final JsonReader jsonReader = Json.createReader( + new StringReader(directDependenciesJson)); + final JsonArray directDependenciesArray = jsonReader.readArray(); + + final var uuidsSeen = new HashSet(); + for (int i = 0; i < directDependenciesArray.size(); i++) { + final JsonObject directDependencyObject = directDependenciesArray.getJsonObject(i); + final String directDependencyUuid = directDependencyObject.getString("uuid"); + if (!uuidsSeen.add(directDependencyUuid)) { + Assert.fail("Duplicate UUID %s in project's directDependencies: %s".formatted( + directDependencyUuid, directDependenciesJson)); + } + } + }); + + final List components = qm.getAllComponents(project); + assertThat(components).allSatisfy(component -> { + if (component.getDirectDependencies() == null) { + return; + } + + final JsonReader jsonReader = Json.createReader( + new StringReader(component.getDirectDependencies())); + final JsonArray directDependenciesArray = jsonReader.readArray(); + + final var uuidsSeen = new HashSet(); + for (int i = 0; i < directDependenciesArray.size(); i++) { + final JsonObject directDependencyObject = directDependenciesArray.getJsonObject(i); + final String directDependencyUuid = directDependencyObject.getString("uuid"); + if (!uuidsSeen.add(directDependencyUuid)) { + Assert.fail("Duplicate UUID %s in component's directDependencies: %s".formatted( + directDependencyUuid, component.getDirectDependencies())); + } + } + }); + } + private void awaitBomProcessedNotification(final BomUploadEvent bomUploadEvent) { try { await("BOM Processed Notification") diff --git a/src/test/resources/unit/bom-issue4455.json b/src/test/resources/unit/bom-issue4455.json new file mode 100644 index 0000000000..39edb46e1c --- /dev/null +++ b/src/test/resources/unit/bom-issue4455.json @@ -0,0 +1,1168 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:25672232-e96e-4805-ae65-5b467011be95", + "version": 1, + "metadata": { + "timestamp": "2024-12-11T11:19:03+00:00", + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "0.54.1" + } + ] + }, + "component": { + "bom-ref": "637c4bf5-b86d-424c-868a-0381ba583f04", + "type": "container", + "name": "trivy-test-image", + "properties": [ + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:19d27b3e4d914c8e7dcf27ad6b162da12bde3e27a020de147a407a0486a0cd8c" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:1b1f9a92db58fcb5b3efa16a33c81cebae7291c98aedb515d5b13c0d86ea7f48" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:41614d4447b3bff6f2389f2e06535b4c42bc09647ef7a812dcde7e71081e6644" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:43f0e35c522ec41b59991888c508ea613d7ee40e83ae062bbd317adf83fb39d8" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:50f9a8dfb75485afcafef620622770c4ccf39e6b61ba51cd568e3a1012ac7b8a" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:83f8cd53869bc3cb71b40dc09952b6d184bc5b2e4d4e1fda716e3a50f9c3329d" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:a4f0c1f6f97572dfea3c26ebf025502958c7451da96fdbe0d71f52173e1ff843" + }, + { + "name": "aquasecurity:trivy:DiffID", + "value": "sha256:f4e1ecd6372909fbd15cd20cce857c75d5f9391b9ce384dbffa337946a607bfa" + }, + { + "name": "aquasecurity:trivy:ImageID", + "value": "sha256:6f18d4201ce58358a69382379a2788dec85de3f8a75c2fcb83e211f3243ec8a5" + }, + { + "name": "aquasecurity:trivy:RepoTag", + "value": "trivy-test-image:latest" + }, + { + "name": "aquasecurity:trivy:SchemaVersion", + "value": "2" + } + ] + } + }, + "components": [ + { + "bom-ref": "74c1f283-c6d5-4a13-b57c-4041498c88e1", + "type": "operating-system", + "name": "alpine", + "version": "3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:Class", + "value": "os-pkgs" + }, + { + "name": "aquasecurity:trivy:Type", + "value": "alpine" + } + ] + }, + { + "bom-ref": "bd6c14ea-b7f0-4324-aed0-fb2c81e2e659", + "type": "library", + "group": "org.dom4j", + "name": "dom4j", + "version": "2.1.4", + "purl": "pkg:maven/org.dom4j/dom4j@2.1.4", + "properties": [ + { + "name": "aquasecurity:trivy:FilePath", + "value": "opt/redacted/install_path_1/dom4j-2.1.4.jar" + }, + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:83f8cd53869bc3cb71b40dc09952b6d184bc5b2e4d4e1fda716e3a50f9c3329d" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "jar" + } + ] + }, + { + "bom-ref": "ed14c90e-c5b2-453c-bcf4-ac213d9c6cb5", + "type": "library", + "group": "org.dom4j", + "name": "dom4j", + "version": "2.1.4", + "purl": "pkg:maven/org.dom4j/dom4j@2.1.4", + "properties": [ + { + "name": "aquasecurity:trivy:FilePath", + "value": "opt/redacted/install_path_2/dom4j-2.1.4.jar" + }, + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:19d27b3e4d914c8e7dcf27ad6b162da12bde3e27a020de147a407a0486a0cd8c" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "jar" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/alpine-baselayout-data@3.6.5-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "alpine-baselayout-data", + "version": "3.6.5-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "ee68a6fb02f7e62304b428b0404a2fc1e2fc353d" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/alpine-baselayout-data@3.6.5-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "alpine-baselayout-data@3.6.5-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "alpine-baselayout" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "3.6.5-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/alpine-baselayout@3.6.5-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "alpine-baselayout", + "version": "3.6.5-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "a8a719fa3db7c6cb005e681086438ef1d1e76d6c" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/alpine-baselayout@3.6.5-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "alpine-baselayout@3.6.5-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "alpine-baselayout" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "3.6.5-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/alpine-keys@2.4-r1?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "alpine-keys", + "version": "2.4-r1", + "hashes": [ + { + "alg": "SHA-1", + "content": "78ab5150a3919e474204e0f91972d1cf0a344f9d" + } + ], + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:apk/alpine/alpine-keys@2.4-r1?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "alpine-keys@2.4-r1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "alpine-keys" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "2.4-r1" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/apk-tools@2.14.4-r1?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "apk-tools", + "version": "2.14.4-r1", + "hashes": [ + { + "alg": "SHA-1", + "content": "fdf8628c985a91660f2e8d740f19ac50b9372f98" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/apk-tools@2.14.4-r1?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:a4f0c1f6f97572dfea3c26ebf025502958c7451da96fdbe0d71f52173e1ff843" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "apk-tools@2.14.4-r1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "apk-tools" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "2.14.4-r1" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/bash@5.2.26-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "bash", + "version": "5.2.26-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "4fbc9b6abbbb735f61cbd80d59b40d75d5a2c853" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-3.0" + } + } + ], + "purl": "pkg:apk/alpine/bash@5.2.26-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:50f9a8dfb75485afcafef620622770c4ccf39e6b61ba51cd568e3a1012ac7b8a" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "bash@5.2.26-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "bash" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "5.2.26-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/busybox-binsh@1.36.1-r29?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "busybox-binsh", + "version": "1.36.1-r29", + "hashes": [ + { + "alg": "SHA-1", + "content": "8758e1e06605e5818449aff862e105b80b6f34bf" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/busybox-binsh@1.36.1-r29?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "busybox-binsh@1.36.1-r29" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "busybox" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.36.1-r29" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/busybox@1.36.1-r29?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "busybox", + "version": "1.36.1-r29", + "hashes": [ + { + "alg": "SHA-1", + "content": "c98f2584c17556181e8098247177ea68d69b0c9c" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/busybox@1.36.1-r29?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "busybox@1.36.1-r29" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "busybox" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.36.1-r29" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/ca-certificates-bundle@20240705-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "ca-certificates-bundle", + "version": "20240705-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "a927e8d0fd49c6cff7692a115ce237ed1bd62894" + } + ], + "licenses": [ + { + "license": { + "name": "MPL-2.0" + } + }, + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:apk/alpine/ca-certificates-bundle@20240705-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "ca-certificates-bundle@20240705-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "ca-certificates" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "20240705-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/jq@1.7.1-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "jq", + "version": "1.7.1-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "db874e07e38cd4863d8cf235966dbb713eb0bc4c" + } + ], + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:apk/alpine/jq@1.7.1-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:1b1f9a92db58fcb5b3efa16a33c81cebae7291c98aedb515d5b13c0d86ea7f48" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "jq@1.7.1-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "jq" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.7.1-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/libcrypto3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "libcrypto3", + "version": "3.3.2-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "9bf0618d6c5fa68e03e5c2bb47d179320f7576ba" + } + ], + "licenses": [ + { + "license": { + "name": "Apache-2.0" + } + } + ], + "purl": "pkg:apk/alpine/libcrypto3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "libcrypto3@3.3.2-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "openssl" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "3.3.2-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/libncursesw@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "libncursesw", + "version": "6.4_p20240420-r1", + "hashes": [ + { + "alg": "SHA-1", + "content": "ea11d954db1aef9ade8abe50bf3870c994a39c70" + } + ], + "licenses": [ + { + "license": { + "name": "X11" + } + } + ], + "purl": "pkg:apk/alpine/libncursesw@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:50f9a8dfb75485afcafef620622770c4ccf39e6b61ba51cd568e3a1012ac7b8a" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "libncursesw@6.4_p20240420-r1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "ncurses" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "6.4_p20240420-r1" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/libssl3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "libssl3", + "version": "3.3.2-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "f81052a84c5e1028fe4db48e94c94ab1a826a898" + } + ], + "licenses": [ + { + "license": { + "name": "Apache-2.0" + } + } + ], + "purl": "pkg:apk/alpine/libssl3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "libssl3@3.3.2-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "openssl" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "3.3.2-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/musl-utils@1.2.5-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "musl-utils", + "version": "1.2.5-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "e11671e426dc2d8189155906d007c39be1eb1367" + } + ], + "licenses": [ + { + "license": { + "name": "MIT" + } + }, + { + "license": { + "name": "BSD-2-Clause" + } + }, + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/musl-utils@1.2.5-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "musl-utils@1.2.5-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "musl" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.2.5-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "musl", + "version": "1.2.5-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "3d2da235e1c31f7045e9382a48cbbfa5c7375c86" + } + ], + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "musl@1.2.5-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "musl" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.2.5-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/ncurses-terminfo-base@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "ncurses-terminfo-base", + "version": "6.4_p20240420-r1", + "hashes": [ + { + "alg": "SHA-1", + "content": "b94ecaed3ab420de295b36edb80b60ce311c4239" + } + ], + "licenses": [ + { + "license": { + "name": "X11" + } + } + ], + "purl": "pkg:apk/alpine/ncurses-terminfo-base@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:50f9a8dfb75485afcafef620622770c4ccf39e6b61ba51cd568e3a1012ac7b8a" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "ncurses-terminfo-base@6.4_p20240420-r1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "ncurses" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "6.4_p20240420-r1" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/oniguruma@6.9.9-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "oniguruma", + "version": "6.9.9-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "2c29b1278471ca8cc10785dfd7a1a4c84444fe05" + } + ], + "licenses": [ + { + "license": { + "name": "BSD-2-Clause" + } + } + ], + "purl": "pkg:apk/alpine/oniguruma@6.9.9-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:1b1f9a92db58fcb5b3efa16a33c81cebae7291c98aedb515d5b13c0d86ea7f48" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "oniguruma@6.9.9-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "oniguruma" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "6.9.9-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/readline@8.2.10-r0?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "readline", + "version": "8.2.10-r0", + "hashes": [ + { + "alg": "SHA-1", + "content": "4a9a680cad09eaf9918906e628376c4ad8269731" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-3.0" + } + } + ], + "purl": "pkg:apk/alpine/readline@8.2.10-r0?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:50f9a8dfb75485afcafef620622770c4ccf39e6b61ba51cd568e3a1012ac7b8a" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "readline@8.2.10-r0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "readline" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "8.2.10-r0" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/scanelf@1.3.7-r2?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "scanelf", + "version": "1.3.7-r2", + "hashes": [ + { + "alg": "SHA-1", + "content": "c84b0b49111485cb08744822f9b34a9fa9524fcc" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/scanelf@1.3.7-r2?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "scanelf@1.3.7-r2" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "pax-utils" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.3.7-r2" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/ssl_client@1.36.1-r29?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "ssl_client", + "version": "1.36.1-r29", + "hashes": [ + { + "alg": "SHA-1", + "content": "7e2867092a0edee7436f70e4430b6b7dde363094" + } + ], + "licenses": [ + { + "license": { + "name": "GPL-2.0" + } + } + ], + "purl": "pkg:apk/alpine/ssl_client@1.36.1-r29?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "ssl_client@1.36.1-r29" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "busybox" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.36.1-r29" + } + ] + }, + { + "bom-ref": "pkg:apk/alpine/zlib@1.3.1-r1?arch=x86_64&distro=3.20.3", + "type": "library", + "name": "zlib", + "version": "1.3.1-r1", + "hashes": [ + { + "alg": "SHA-1", + "content": "9ba6f253e2982e0e6e71cb4187e3d6b6c4bbae99" + } + ], + "licenses": [ + { + "license": { + "name": "Zlib" + } + } + ], + "purl": "pkg:apk/alpine/zlib@1.3.1-r1?arch=x86_64&distro=3.20.3", + "properties": [ + { + "name": "aquasecurity:trivy:LayerDiffID", + "value": "sha256:63ca1fbb43ae5034640e5e6cb3e083e05c290072c5366fcaa9d62435a4cced85" + }, + { + "name": "aquasecurity:trivy:PkgID", + "value": "zlib@1.3.1-r1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "alpine" + }, + { + "name": "aquasecurity:trivy:SrcName", + "value": "zlib" + }, + { + "name": "aquasecurity:trivy:SrcVersion", + "value": "1.3.1-r1" + } + ] + } + ], + "dependencies": [ + { + "ref": "637c4bf5-b86d-424c-868a-0381ba583f04", + "dependsOn": [ + "74c1f283-c6d5-4a13-b57c-4041498c88e1", + "bd6c14ea-b7f0-4324-aed0-fb2c81e2e659", + "ed14c90e-c5b2-453c-bcf4-ac213d9c6cb5" + ] + }, + { + "ref": "74c1f283-c6d5-4a13-b57c-4041498c88e1", + "dependsOn": [ + "pkg:apk/alpine/alpine-baselayout-data@3.6.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/alpine-baselayout@3.6.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/alpine-keys@2.4-r1?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/apk-tools@2.14.4-r1?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/bash@5.2.26-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/busybox-binsh@1.36.1-r29?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/busybox@1.36.1-r29?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/ca-certificates-bundle@20240705-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/jq@1.7.1-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/libcrypto3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/libncursesw@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/libssl3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/musl-utils@1.2.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/ncurses-terminfo-base@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/oniguruma@6.9.9-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/readline@8.2.10-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/scanelf@1.3.7-r2?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/ssl_client@1.36.1-r29?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/zlib@1.3.1-r1?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "bd6c14ea-b7f0-4324-aed0-fb2c81e2e659", + "dependsOn": [] + }, + { + "ref": "ed14c90e-c5b2-453c-bcf4-ac213d9c6cb5", + "dependsOn": [] + }, + { + "ref": "pkg:apk/alpine/alpine-baselayout-data@3.6.5-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [] + }, + { + "ref": "pkg:apk/alpine/alpine-baselayout@3.6.5-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/alpine-baselayout-data@3.6.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/busybox-binsh@1.36.1-r29?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/alpine-keys@2.4-r1?arch=x86_64&distro=3.20.3", + "dependsOn": [] + }, + { + "ref": "pkg:apk/alpine/apk-tools@2.14.4-r1?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/ca-certificates-bundle@20240705-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/libcrypto3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/libssl3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/zlib@1.3.1-r1?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/bash@5.2.26-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/busybox-binsh@1.36.1-r29?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/readline@8.2.10-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/busybox-binsh@1.36.1-r29?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/busybox@1.36.1-r29?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/busybox@1.36.1-r29?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/ca-certificates-bundle@20240705-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [] + }, + { + "ref": "pkg:apk/alpine/jq@1.7.1-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/oniguruma@6.9.9-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/libcrypto3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/libncursesw@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/ncurses-terminfo-base@6.4_p20240420-r1?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/libssl3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/libcrypto3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/musl-utils@1.2.5-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/scanelf@1.3.7-r2?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [] + }, + { + "ref": "pkg:apk/alpine/ncurses-terminfo-base@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "dependsOn": [] + }, + { + "ref": "pkg:apk/alpine/oniguruma@6.9.9-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/readline@8.2.10-r0?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/libncursesw@6.4_p20240420-r1?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/scanelf@1.3.7-r2?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/ssl_client@1.36.1-r29?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/libcrypto3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/libssl3@3.3.2-r0?arch=x86_64&distro=3.20.3", + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + }, + { + "ref": "pkg:apk/alpine/zlib@1.3.1-r1?arch=x86_64&distro=3.20.3", + "dependsOn": [ + "pkg:apk/alpine/musl@1.2.5-r0?arch=x86_64&distro=3.20.3" + ] + } + ], + "vulnerabilities": [] +} \ No newline at end of file