diff --git a/integration/convert_test.go b/integration/convert_test.go new file mode 100644 index 000000000000..803ba538dcba --- /dev/null +++ b/integration/convert_test.go @@ -0,0 +1,69 @@ +//go:build integration + +package integration + +import ( + "path/filepath" + "testing" + + "github.com/aquasecurity/trivy/pkg/types" +) + +func TestConvert(t *testing.T) { + type args struct { + input string + format string + scanners string + } + tests := []struct { + name string + args args + golden string + override OverrideFunc + }{ + { + name: "npm", + args: args{ + input: "testdata/npm.json.golden", + format: "cyclonedx", + }, + golden: "testdata/npm-cyclonedx.json.golden", + }, + { + name: "npm without package UID", + args: args{ + input: "testdata/fixtures/convert/npm.json.golden", + format: "cyclonedx", + }, + golden: "testdata/npm-cyclonedx.json.golden", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + osArgs := []string{ + "convert", + "--cache-dir", + t.TempDir(), + "-q", + "--format", + tt.args.format, + } + + // Set up the output file + outputFile := filepath.Join(t.TempDir(), "output.json") + if *update { + outputFile = tt.golden + } + + osArgs = append(osArgs, "--output", outputFile) + osArgs = append(osArgs, tt.args.input) + + // Run "trivy convert" + runTest(t, osArgs, tt.golden, outputFile, types.Format(tt.args.format), runOptions{ + fakeUUID: "3ff14136-e09f-4df9-80ea-%012d", + }) + }) + } + +} diff --git a/integration/testdata/fixtures/convert/npm.json.golden b/integration/testdata/fixtures/convert/npm.json.golden new file mode 100644 index 000000000000..a576da82c72e --- /dev/null +++ b/integration/testdata/fixtures/convert/npm.json.golden @@ -0,0 +1,381 @@ +{ + "SchemaVersion": 2, + "CreatedAt": "2021-08-25T12:20:30.000000005Z", + "ArtifactName": "testdata/fixtures/repo/npm", + "ArtifactType": "repository", + "Metadata": { + "ImageConfig": { + "architecture": "", + "created": "0001-01-01T00:00:00Z", + "os": "", + "rootfs": { + "type": "", + "diff_ids": null + }, + "config": {} + } + }, + "Results": [ + { + "Target": "package-lock.json", + "Class": "lang-pkgs", + "Type": "npm", + "Packages": [ + { + "ID": "asap@2.0.6", + "Name": "asap", + "Identifier": { + "PURL": "pkg:npm/asap@2.0.6" + }, + "Version": "2.0.6", + "Layer": {}, + "Locations": [ + { + "StartLine": 6, + "EndLine": 10 + } + ] + }, + { + "ID": "jquery@3.3.9", + "Name": "jquery", + "Identifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, + "Version": "3.3.9", + "Licenses": [ + "MIT" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 11, + "EndLine": 15 + } + ] + }, + { + "ID": "js-tokens@4.0.0", + "Name": "js-tokens", + "Identifier": { + "PURL": "pkg:npm/js-tokens@4.0.0" + }, + "Version": "4.0.0", + "Layer": {}, + "Locations": [ + { + "StartLine": 16, + "EndLine": 20 + } + ] + }, + { + "ID": "loose-envify@1.4.0", + "Name": "loose-envify", + "Identifier": { + "PURL": "pkg:npm/loose-envify@1.4.0" + }, + "Version": "1.4.0", + "DependsOn": [ + "js-tokens@4.0.0" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 21, + "EndLine": 28 + } + ] + }, + { + "ID": "object-assign@4.1.1", + "Name": "object-assign", + "Identifier": { + "PURL": "pkg:npm/object-assign@4.1.1" + }, + "Version": "4.1.1", + "Layer": {}, + "Locations": [ + { + "StartLine": 29, + "EndLine": 33 + } + ] + }, + { + "ID": "promise@8.0.3", + "Name": "promise", + "Identifier": { + "PURL": "pkg:npm/promise@8.0.3" + }, + "Version": "8.0.3", + "Licenses": [ + "MIT" + ], + "DependsOn": [ + "asap@2.0.6" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 34, + "EndLine": 41 + } + ] + }, + { + "ID": "prop-types@15.7.2", + "Name": "prop-types", + "Identifier": { + "PURL": "pkg:npm/prop-types@15.7.2" + }, + "Version": "15.7.2", + "DependsOn": [ + "loose-envify@1.4.0", + "object-assign@4.1.1", + "react-is@16.8.6" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 42, + "EndLine": 51 + } + ] + }, + { + "ID": "react@16.8.6", + "Name": "react", + "Identifier": { + "PURL": "pkg:npm/react@16.8.6" + }, + "Version": "16.8.6", + "Licenses": [ + "MIT" + ], + "DependsOn": [ + "loose-envify@1.4.0", + "object-assign@4.1.1", + "prop-types@15.7.2", + "scheduler@0.13.6" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 52, + "EndLine": 62 + } + ] + }, + { + "ID": "react-is@16.8.6", + "Name": "react-is", + "Identifier": { + "PURL": "pkg:npm/react-is@16.8.6" + }, + "Version": "16.8.6", + "Licenses": [ + "MIT" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 63, + "EndLine": 67 + } + ] + }, + { + "ID": "redux@4.0.1", + "Name": "redux", + "Identifier": { + "PURL": "pkg:npm/redux@4.0.1" + }, + "Version": "4.0.1", + "Licenses": [ + "MIT" + ], + "DependsOn": [ + "loose-envify@1.4.0", + "symbol-observable@1.2.0" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 68, + "EndLine": 76 + } + ] + }, + { + "ID": "scheduler@0.13.6", + "Name": "scheduler", + "Identifier": { + "PURL": "pkg:npm/scheduler@0.13.6" + }, + "Version": "0.13.6", + "DependsOn": [ + "loose-envify@1.4.0", + "object-assign@4.1.1" + ], + "Layer": {}, + "Locations": [ + { + "StartLine": 77, + "EndLine": 85 + } + ] + }, + { + "ID": "symbol-observable@1.2.0", + "Name": "symbol-observable", + "Identifier": { + "PURL": "pkg:npm/symbol-observable@1.2.0" + }, + "Version": "1.2.0", + "Layer": {}, + "Locations": [ + { + "StartLine": 86, + "EndLine": 90 + } + ] + } + ], + "Vulnerabilities": [ + { + "VulnerabilityID": "CVE-2019-11358", + "PkgID": "jquery@3.3.9", + "PkgName": "jquery", + "PkgIdentifier": { + "PURL": "pkg:npm/jquery@3.3.9" + }, + "InstalledVersion": "3.3.9", + "FixedVersion": "3.4.0", + "Status": "fixed", + "Layer": {}, + "SeveritySource": "ghsa", + "PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-11358", + "DataSource": { + "ID": "ghsa", + "Name": "GitHub Security Advisory Npm", + "URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "Title": "jquery: Prototype pollution in object's prototype leading to denial of service, remote code execution, or property injection", + "Description": "jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.", + "Severity": "MEDIUM", + "CweIDs": [ + "CWE-79" + ], + "VendorSeverity": { + "alma": 2, + "amazon": 2, + "arch-linux": 2, + "ghsa": 2, + "nodejs-security-wg": 2, + "nvd": 2, + "oracle-oval": 2, + "redhat": 2, + "ruby-advisory-db": 2, + "ubuntu": 1 + }, + "CVSS": { + "nvd": { + "V2Vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N", + "V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", + "V2Score": 4.3, + "V3Score": 6.1 + }, + "redhat": { + "V3Vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", + "V3Score": 5.6 + } + }, + "References": [ + "http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00006.html", + "http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00025.html", + "http://packetstormsecurity.com/files/152787/dotCMS-5.1.1-Vulnerable-Dependencies.html", + "http://packetstormsecurity.com/files/153237/RetireJS-CORS-Issue-Script-Execution.html", + "http://packetstormsecurity.com/files/156743/OctoberCMS-Insecure-Dependencies.html", + "http://seclists.org/fulldisclosure/2019/May/10", + "http://seclists.org/fulldisclosure/2019/May/11", + "http://seclists.org/fulldisclosure/2019/May/13", + "http://www.openwall.com/lists/oss-security/2019/06/03/2", + "http://www.securityfocus.com/bid/108023", + "https://access.redhat.com/errata/RHBA-2019:1570", + "https://access.redhat.com/errata/RHSA-2019:1456", + "https://access.redhat.com/errata/RHSA-2019:2587", + "https://access.redhat.com/errata/RHSA-2019:3023", + "https://access.redhat.com/errata/RHSA-2019:3024", + "https://access.redhat.com/security/cve/CVE-2019-11358", + "https://backdropcms.org/security/backdrop-sa-core-2019-009", + "https://blog.jquery.com/2019/04/10/jquery-3-4-0-released/", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11358", + "https://github.com/DanielRuf/snyk-js-jquery-174006?files=1", + "https://github.com/advisories/GHSA-6c3j-c64m-qhgq", + "https://github.com/jquery/jquery/commit/753d591aea698e57d6db58c9f722cd0808619b1b", + "https://github.com/jquery/jquery/pull/4333", + "https://github.com/rails/jquery-rails/blob/master/CHANGELOG.md#434", + "https://hackerone.com/reports/454365", + "https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44601", + "https://linux.oracle.com/cve/CVE-2019-11358.html", + "https://linux.oracle.com/errata/ELSA-2020-4847.html", + "https://lists.apache.org/thread.html/08720ef215ee7ab3386c05a1a90a7d1c852bf0706f176a7816bf65fc@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/519eb0fd45642dcecd9ff74cb3e71c20a4753f7d82e2f07864b5108f@%3Cdev.drill.apache.org%3E", + "https://lists.apache.org/thread.html/5928aa293e39d248266472210c50f176cac1535220f2486e6a7fa844@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/6097cdbd6f0a337bedd9bb5cc441b2d525ff002a96531de367e4259f@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/88fb0362fd40e5b605ea8149f63241537b8b6fb5bfa315391fc5cbb7@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/b0656d359c7d40ec9f39c8cc61bca66802ef9a2a12ee199f5b0c1442@%3Cdev.drill.apache.org%3E", + "https://lists.apache.org/thread.html/b736d0784cf02f5a30fbb4c5902762a15ad6d47e17e2c5a17b7d6205@%3Ccommits.airflow.apache.org%3E", + "https://lists.apache.org/thread.html/ba79cf1658741e9f146e4c59b50aee56656ea95d841d358d006c18b6@%3Ccommits.roller.apache.org%3E", + "https://lists.apache.org/thread.html/bcce5a9c532b386c68dab2f6b3ce8b0cc9b950ec551766e76391caa3@%3Ccommits.nifi.apache.org%3E", + "https://lists.apache.org/thread.html/f9bc3e55f4e28d1dcd1a69aae6d53e609a758e34d2869b4d798e13cc@%3Cissues.drill.apache.org%3E", + "https://lists.apache.org/thread.html/r2041a75d3fc09dec55adfd95d598b38d22715303f65c997c054844c9@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r2baacab6e0acb5a2092eb46ae04fd6c3e8277b4fd79b1ffb7f3254fa@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r38f0d1aa3c923c22977fe7376508f030f22e22c1379fbb155bf29766@%3Cdev.syncope.apache.org%3E", + "https://lists.apache.org/thread.html/r41b5bfe009c845f67d4f68948cc9419ac2d62e287804aafd72892b08@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r7aac081cbddb6baa24b75e74abf0929bf309b176755a53e3ed810355@%3Cdev.flink.apache.org%3E", + "https://lists.apache.org/thread.html/r7d64895cc4dff84d0becfc572b20c0e4bf9bfa7b10c6f5f73e783734@%3Cdev.storm.apache.org%3E", + "https://lists.apache.org/thread.html/r7e8ebccb7c022e41295f6fdb7b971209b83702339f872ddd8cf8bf73@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/rac25da84ecdcd36f6de5ad0d255f4e967209bbbebddb285e231da37d@%3Cissues.flink.apache.org%3E", + "https://lists.apache.org/thread.html/rca37935d661f4689cb4119f1b3b224413b22be161b678e6e6ce0c69b@%3Ccommits.nifi.apache.org%3E", + "https://lists.debian.org/debian-lts-announce/2019/05/msg00006.html", + "https://lists.debian.org/debian-lts-announce/2019/05/msg00029.html", + "https://lists.debian.org/debian-lts-announce/2020/02/msg00024.html", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/4UOAZIFCSZ3ENEFOR5IXX6NFAD3HV7FA/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/5IABSKTYZ5JUGL735UKGXL5YPRYOPUYI/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KYH3OAGR2RTCHRA5NOKX2TES7SNQMWGO/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QV3PKZC3PQCO3273HAT76PAQZFBEO4KP/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RLXRX23725JL366CNZGJZ7AQQB7LHQ6F/", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/WZW27UCJ5CYFL4KFFFMYMIBNMIU2ALG5/", + "https://nvd.nist.gov/vuln/detail/CVE-2019-11358", + "https://seclists.org/bugtraq/2019/Apr/32", + "https://seclists.org/bugtraq/2019/Jun/12", + "https://seclists.org/bugtraq/2019/May/18", + "https://security.netapp.com/advisory/ntap-20190919-0001/", + "https://snyk.io/vuln/SNYK-JS-JQUERY-174006", + "https://www.debian.org/security/2019/dsa-4434", + "https://www.debian.org/security/2019/dsa-4460", + "https://www.drupal.org/sa-core-2019-006", + "https://www.oracle.com//security-alerts/cpujul2021.html", + "https://www.oracle.com/security-alerts/cpuApr2021.html", + "https://www.oracle.com/security-alerts/cpuapr2020.html", + "https://www.oracle.com/security-alerts/cpujan2020.html", + "https://www.oracle.com/security-alerts/cpujan2021.html", + "https://www.oracle.com/security-alerts/cpujul2020.html", + "https://www.oracle.com/security-alerts/cpuoct2020.html", + "https://www.oracle.com/security-alerts/cpuoct2021.html", + "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html", + "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html", + "https://www.privacy-wise.com/mitigating-cve-2019-11358-in-old-versions-of-jquery/", + "https://www.synology.com/security/advisory/Synology_SA_19_19", + "https://www.tenable.com/security/tns-2019-08", + "https://www.tenable.com/security/tns-2020-02" + ], + "PublishedDate": "2019-04-20T00:29:00Z", + "LastModifiedDate": "2021-10-20T11:15:00Z" + } + ] + } + ] +} diff --git a/integration/testdata/npm-cyclonedx.json.golden b/integration/testdata/npm-cyclonedx.json.golden new file mode 100644 index 000000000000..d7bcc56af462 --- /dev/null +++ b/integration/testdata/npm-cyclonedx.json.golden @@ -0,0 +1,725 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:3ff14136-e09f-4df9-80ea-000000000015", + "version": 1, + "metadata": { + "timestamp": "2021-08-25T12:20:30+00:00", + "tools": { + "components": [ + { + "type": "application", + "group": "aquasecurity", + "name": "trivy", + "version": "dev" + } + ] + }, + "component": { + "bom-ref": "3ff14136-e09f-4df9-80ea-000000000001", + "type": "application", + "name": "testdata/fixtures/repo/npm", + "properties": [ + { + "name": "aquasecurity:trivy:SchemaVersion", + "value": "2" + } + ] + } + }, + "components": [ + { + "bom-ref": "3ff14136-e09f-4df9-80ea-000000000002", + "type": "application", + "name": "package-lock.json", + "properties": [ + { + "name": "aquasecurity:trivy:Class", + "value": "lang-pkgs" + }, + { + "name": "aquasecurity:trivy:Type", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/asap@2.0.6", + "type": "library", + "name": "asap", + "version": "2.0.6", + "purl": "pkg:npm/asap@2.0.6", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "asap@2.0.6" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/jquery@3.3.9", + "type": "library", + "name": "jquery", + "version": "3.3.9", + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:npm/jquery@3.3.9", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "jquery@3.3.9" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/js-tokens@4.0.0", + "type": "library", + "name": "js-tokens", + "version": "4.0.0", + "purl": "pkg:npm/js-tokens@4.0.0", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "js-tokens@4.0.0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/loose-envify@1.4.0", + "type": "library", + "name": "loose-envify", + "version": "1.4.0", + "purl": "pkg:npm/loose-envify@1.4.0", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "loose-envify@1.4.0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/object-assign@4.1.1", + "type": "library", + "name": "object-assign", + "version": "4.1.1", + "purl": "pkg:npm/object-assign@4.1.1", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "object-assign@4.1.1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/promise@8.0.3", + "type": "library", + "name": "promise", + "version": "8.0.3", + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:npm/promise@8.0.3", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "promise@8.0.3" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/prop-types@15.7.2", + "type": "library", + "name": "prop-types", + "version": "15.7.2", + "purl": "pkg:npm/prop-types@15.7.2", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "prop-types@15.7.2" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/react-is@16.8.6", + "type": "library", + "name": "react-is", + "version": "16.8.6", + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:npm/react-is@16.8.6", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "react-is@16.8.6" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/react@16.8.6", + "type": "library", + "name": "react", + "version": "16.8.6", + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:npm/react@16.8.6", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "react@16.8.6" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/redux@4.0.1", + "type": "library", + "name": "redux", + "version": "4.0.1", + "licenses": [ + { + "license": { + "name": "MIT" + } + } + ], + "purl": "pkg:npm/redux@4.0.1", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "redux@4.0.1" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/scheduler@0.13.6", + "type": "library", + "name": "scheduler", + "version": "0.13.6", + "purl": "pkg:npm/scheduler@0.13.6", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "scheduler@0.13.6" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + }, + { + "bom-ref": "pkg:npm/symbol-observable@1.2.0", + "type": "library", + "name": "symbol-observable", + "version": "1.2.0", + "purl": "pkg:npm/symbol-observable@1.2.0", + "properties": [ + { + "name": "aquasecurity:trivy:PkgID", + "value": "symbol-observable@1.2.0" + }, + { + "name": "aquasecurity:trivy:PkgType", + "value": "npm" + } + ] + } + ], + "dependencies": [ + { + "ref": "3ff14136-e09f-4df9-80ea-000000000001", + "dependsOn": [ + "3ff14136-e09f-4df9-80ea-000000000002" + ] + }, + { + "ref": "3ff14136-e09f-4df9-80ea-000000000002", + "dependsOn": [ + "pkg:npm/asap@2.0.6", + "pkg:npm/jquery@3.3.9", + "pkg:npm/js-tokens@4.0.0", + "pkg:npm/loose-envify@1.4.0", + "pkg:npm/object-assign@4.1.1", + "pkg:npm/promise@8.0.3", + "pkg:npm/prop-types@15.7.2", + "pkg:npm/react-is@16.8.6", + "pkg:npm/react@16.8.6", + "pkg:npm/redux@4.0.1", + "pkg:npm/scheduler@0.13.6", + "pkg:npm/symbol-observable@1.2.0" + ] + }, + { + "ref": "pkg:npm/asap@2.0.6", + "dependsOn": [] + }, + { + "ref": "pkg:npm/jquery@3.3.9", + "dependsOn": [] + }, + { + "ref": "pkg:npm/js-tokens@4.0.0", + "dependsOn": [] + }, + { + "ref": "pkg:npm/loose-envify@1.4.0", + "dependsOn": [ + "pkg:npm/js-tokens@4.0.0" + ] + }, + { + "ref": "pkg:npm/object-assign@4.1.1", + "dependsOn": [] + }, + { + "ref": "pkg:npm/promise@8.0.3", + "dependsOn": [ + "pkg:npm/asap@2.0.6" + ] + }, + { + "ref": "pkg:npm/prop-types@15.7.2", + "dependsOn": [ + "pkg:npm/loose-envify@1.4.0", + "pkg:npm/object-assign@4.1.1", + "pkg:npm/react-is@16.8.6" + ] + }, + { + "ref": "pkg:npm/react-is@16.8.6", + "dependsOn": [] + }, + { + "ref": "pkg:npm/react@16.8.6", + "dependsOn": [ + "pkg:npm/loose-envify@1.4.0", + "pkg:npm/object-assign@4.1.1", + "pkg:npm/prop-types@15.7.2", + "pkg:npm/scheduler@0.13.6" + ] + }, + { + "ref": "pkg:npm/redux@4.0.1", + "dependsOn": [ + "pkg:npm/loose-envify@1.4.0", + "pkg:npm/symbol-observable@1.2.0" + ] + }, + { + "ref": "pkg:npm/scheduler@0.13.6", + "dependsOn": [ + "pkg:npm/loose-envify@1.4.0", + "pkg:npm/object-assign@4.1.1" + ] + }, + { + "ref": "pkg:npm/symbol-observable@1.2.0", + "dependsOn": [] + } + ], + "vulnerabilities": [ + { + "id": "CVE-2019-11358", + "source": { + "name": "ghsa", + "url": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Anpm" + }, + "ratings": [ + { + "source": { + "name": "alma" + }, + "severity": "medium" + }, + { + "source": { + "name": "amazon" + }, + "severity": "medium" + }, + { + "source": { + "name": "arch-linux" + }, + "severity": "medium" + }, + { + "source": { + "name": "ghsa" + }, + "severity": "medium" + }, + { + "source": { + "name": "nodejs-security-wg" + }, + "severity": "medium" + }, + { + "source": { + "name": "nvd" + }, + "score": 4.3, + "severity": "medium", + "method": "CVSSv2", + "vector": "AV:N/AC:M/Au:N/C:N/I:P/A:N" + }, + { + "source": { + "name": "nvd" + }, + "score": 6.1, + "severity": "medium", + "method": "CVSSv31", + "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N" + }, + { + "source": { + "name": "oracle-oval" + }, + "severity": "medium" + }, + { + "source": { + "name": "redhat" + }, + "score": 5.6, + "severity": "medium", + "method": "CVSSv3", + "vector": "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L" + }, + { + "source": { + "name": "ruby-advisory-db" + }, + "severity": "medium" + }, + { + "source": { + "name": "ubuntu" + }, + "severity": "low" + } + ], + "cwes": [ + 79 + ], + "description": "jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.", + "recommendation": "Upgrade jquery to version 3.4.0", + "advisories": [ + { + "url": "https://avd.aquasec.com/nvd/cve-2019-11358" + }, + { + "url": "http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00006.html" + }, + { + "url": "http://lists.opensuse.org/opensuse-security-announce/2019-08/msg00025.html" + }, + { + "url": "http://packetstormsecurity.com/files/152787/dotCMS-5.1.1-Vulnerable-Dependencies.html" + }, + { + "url": "http://packetstormsecurity.com/files/153237/RetireJS-CORS-Issue-Script-Execution.html" + }, + { + "url": "http://packetstormsecurity.com/files/156743/OctoberCMS-Insecure-Dependencies.html" + }, + { + "url": "http://seclists.org/fulldisclosure/2019/May/10" + }, + { + "url": "http://seclists.org/fulldisclosure/2019/May/11" + }, + { + "url": "http://seclists.org/fulldisclosure/2019/May/13" + }, + { + "url": "http://www.openwall.com/lists/oss-security/2019/06/03/2" + }, + { + "url": "http://www.securityfocus.com/bid/108023" + }, + { + "url": "https://access.redhat.com/errata/RHBA-2019:1570" + }, + { + "url": "https://access.redhat.com/errata/RHSA-2019:1456" + }, + { + "url": "https://access.redhat.com/errata/RHSA-2019:2587" + }, + { + "url": "https://access.redhat.com/errata/RHSA-2019:3023" + }, + { + "url": "https://access.redhat.com/errata/RHSA-2019:3024" + }, + { + "url": "https://access.redhat.com/security/cve/CVE-2019-11358" + }, + { + "url": "https://backdropcms.org/security/backdrop-sa-core-2019-009" + }, + { + "url": "https://blog.jquery.com/2019/04/10/jquery-3-4-0-released/" + }, + { + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11358" + }, + { + "url": "https://github.com/DanielRuf/snyk-js-jquery-174006?files=1" + }, + { + "url": "https://github.com/advisories/GHSA-6c3j-c64m-qhgq" + }, + { + "url": "https://github.com/jquery/jquery/commit/753d591aea698e57d6db58c9f722cd0808619b1b" + }, + { + "url": "https://github.com/jquery/jquery/pull/4333" + }, + { + "url": "https://github.com/rails/jquery-rails/blob/master/CHANGELOG.md#434" + }, + { + "url": "https://hackerone.com/reports/454365" + }, + { + "url": "https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44601" + }, + { + "url": "https://linux.oracle.com/cve/CVE-2019-11358.html" + }, + { + "url": "https://linux.oracle.com/errata/ELSA-2020-4847.html" + }, + { + "url": "https://lists.apache.org/thread.html/08720ef215ee7ab3386c05a1a90a7d1c852bf0706f176a7816bf65fc@%3Ccommits.airflow.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/519eb0fd45642dcecd9ff74cb3e71c20a4753f7d82e2f07864b5108f@%3Cdev.drill.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/5928aa293e39d248266472210c50f176cac1535220f2486e6a7fa844@%3Ccommits.airflow.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/6097cdbd6f0a337bedd9bb5cc441b2d525ff002a96531de367e4259f@%3Ccommits.airflow.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/88fb0362fd40e5b605ea8149f63241537b8b6fb5bfa315391fc5cbb7@%3Ccommits.airflow.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/b0656d359c7d40ec9f39c8cc61bca66802ef9a2a12ee199f5b0c1442@%3Cdev.drill.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/b736d0784cf02f5a30fbb4c5902762a15ad6d47e17e2c5a17b7d6205@%3Ccommits.airflow.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/ba79cf1658741e9f146e4c59b50aee56656ea95d841d358d006c18b6@%3Ccommits.roller.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/bcce5a9c532b386c68dab2f6b3ce8b0cc9b950ec551766e76391caa3@%3Ccommits.nifi.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/f9bc3e55f4e28d1dcd1a69aae6d53e609a758e34d2869b4d798e13cc@%3Cissues.drill.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/r2041a75d3fc09dec55adfd95d598b38d22715303f65c997c054844c9@%3Cissues.flink.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/r2baacab6e0acb5a2092eb46ae04fd6c3e8277b4fd79b1ffb7f3254fa@%3Cissues.flink.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/r38f0d1aa3c923c22977fe7376508f030f22e22c1379fbb155bf29766@%3Cdev.syncope.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/r41b5bfe009c845f67d4f68948cc9419ac2d62e287804aafd72892b08@%3Cissues.flink.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/r7aac081cbddb6baa24b75e74abf0929bf309b176755a53e3ed810355@%3Cdev.flink.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/r7d64895cc4dff84d0becfc572b20c0e4bf9bfa7b10c6f5f73e783734@%3Cdev.storm.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/r7e8ebccb7c022e41295f6fdb7b971209b83702339f872ddd8cf8bf73@%3Cissues.flink.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/rac25da84ecdcd36f6de5ad0d255f4e967209bbbebddb285e231da37d@%3Cissues.flink.apache.org%3E" + }, + { + "url": "https://lists.apache.org/thread.html/rca37935d661f4689cb4119f1b3b224413b22be161b678e6e6ce0c69b@%3Ccommits.nifi.apache.org%3E" + }, + { + "url": "https://lists.debian.org/debian-lts-announce/2019/05/msg00006.html" + }, + { + "url": "https://lists.debian.org/debian-lts-announce/2019/05/msg00029.html" + }, + { + "url": "https://lists.debian.org/debian-lts-announce/2020/02/msg00024.html" + }, + { + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/4UOAZIFCSZ3ENEFOR5IXX6NFAD3HV7FA/" + }, + { + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/5IABSKTYZ5JUGL735UKGXL5YPRYOPUYI/" + }, + { + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/KYH3OAGR2RTCHRA5NOKX2TES7SNQMWGO/" + }, + { + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/QV3PKZC3PQCO3273HAT76PAQZFBEO4KP/" + }, + { + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/RLXRX23725JL366CNZGJZ7AQQB7LHQ6F/" + }, + { + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/WZW27UCJ5CYFL4KFFFMYMIBNMIU2ALG5/" + }, + { + "url": "https://nvd.nist.gov/vuln/detail/CVE-2019-11358" + }, + { + "url": "https://seclists.org/bugtraq/2019/Apr/32" + }, + { + "url": "https://seclists.org/bugtraq/2019/Jun/12" + }, + { + "url": "https://seclists.org/bugtraq/2019/May/18" + }, + { + "url": "https://security.netapp.com/advisory/ntap-20190919-0001/" + }, + { + "url": "https://snyk.io/vuln/SNYK-JS-JQUERY-174006" + }, + { + "url": "https://www.debian.org/security/2019/dsa-4434" + }, + { + "url": "https://www.debian.org/security/2019/dsa-4460" + }, + { + "url": "https://www.drupal.org/sa-core-2019-006" + }, + { + "url": "https://www.oracle.com//security-alerts/cpujul2021.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpuApr2021.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpuapr2020.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpujan2020.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpujan2021.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpujul2020.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpuoct2020.html" + }, + { + "url": "https://www.oracle.com/security-alerts/cpuoct2021.html" + }, + { + "url": "https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html" + }, + { + "url": "https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html" + }, + { + "url": "https://www.privacy-wise.com/mitigating-cve-2019-11358-in-old-versions-of-jquery/" + }, + { + "url": "https://www.synology.com/security/advisory/Synology_SA_19_19" + }, + { + "url": "https://www.tenable.com/security/tns-2019-08" + }, + { + "url": "https://www.tenable.com/security/tns-2020-02" + } + ], + "published": "2019-04-20T00:29:00+00:00", + "updated": "2021-10-20T11:15:00+00:00", + "affects": [ + { + "ref": "pkg:npm/jquery@3.3.9", + "versions": [ + { + "version": "3.3.9", + "status": "affected" + } + ] + } + ] + } + ] +} diff --git a/pkg/commands/convert/run.go b/pkg/commands/convert/run.go index 428d6b5b0b4b..584bc6f6bddc 100644 --- a/pkg/commands/convert/run.go +++ b/pkg/commands/convert/run.go @@ -8,6 +8,8 @@ import ( "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/commands/operation" + "github.com/aquasecurity/trivy/pkg/dependency" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/flag" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/report" @@ -35,6 +37,7 @@ func Run(ctx context.Context, opts flag.Options) (err error) { return xerrors.New("AWS and Kubernetes scanning reports are not yet supported") } + compat(&r) if err = result.Filter(ctx, r, opts.FilterOpts()); err != nil { return xerrors.Errorf("unable to filter results: %w", err) } @@ -46,3 +49,30 @@ func Run(ctx context.Context, opts flag.Options) (err error) { return operation.Exit(opts, r.Results.Failed(), r.Metadata) } + +// compat converts the JSON report to the latest format +func compat(r *types.Report) { + for i, res := range r.Results { + pkgs := make(map[string]ftypes.Package, len(res.Packages)) + for j, pkg := range res.Packages { + if pkg.Identifier.UID != "" { + continue + } + // Fill in the UID field since older JSON reports don't have it + pkg.Identifier.UID = dependency.UID(res.Target, pkg) + pkgs[pkg.ID+pkg.FilePath] = pkg + r.Results[i].Packages[j] = pkg + } + + for j, vuln := range res.Vulnerabilities { + if vuln.PkgIdentifier.UID != "" { + continue + } + if pkg, ok := pkgs[vuln.PkgID+vuln.PkgPath]; !ok { + continue + } else { + r.Results[i].Vulnerabilities[j].PkgIdentifier = pkg.Identifier + } + } + } +} diff --git a/pkg/dependency/id.go b/pkg/dependency/id.go index 8f01bf23123a..577ed5d0ac41 100644 --- a/pkg/dependency/id.go +++ b/pkg/dependency/id.go @@ -1,9 +1,13 @@ package dependency import ( + "fmt" "strings" + "github.com/mitchellh/hashstructure/v2" + "github.com/aquasecurity/trivy/pkg/fanal/types" + "github.com/aquasecurity/trivy/pkg/log" ) // ID returns a unique ID for the given library. @@ -30,3 +34,19 @@ func ID(ltype types.LangType, name, version string) string { } return name + sep + version } + +// UID calculates the hash of the package for the unique ID +func UID(filePath string, pkg types.Package) string { + v := map[string]any{ + "filePath": filePath, // To differentiate the hash of the same package but different file path + "pkg": pkg, + } + hash, err := hashstructure.Hash(v, hashstructure.FormatV2, &hashstructure.HashOptions{ + ZeroNil: true, + IgnoreZeroValue: true, + }) + if err != nil { + log.Warn("Failed to calculate the package hash", log.String("pkg", pkg.Name), log.Err(err)) + } + return fmt.Sprintf("%x", hash) +} diff --git a/pkg/fanal/applier/docker.go b/pkg/fanal/applier/docker.go index d4f88bc851a7..c1c21f236b22 100644 --- a/pkg/fanal/applier/docker.go +++ b/pkg/fanal/applier/docker.go @@ -6,10 +6,10 @@ import ( "time" "github.com/knqyf263/nested" - "github.com/mitchellh/hashstructure/v2" "github.com/package-url/packageurl-go" "github.com/samber/lo" + "github.com/aquasecurity/trivy/pkg/dependency" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/log" "github.com/aquasecurity/trivy/pkg/purl" @@ -223,7 +223,7 @@ func ApplyLayers(layers []ftypes.BlobInfo) ftypes.ArtifactDetail { if mergedLayer.OS.Family != "" { mergedLayer.Packages[i].Identifier.PURL = newPURL(mergedLayer.OS.Family, types.Metadata{OS: &mergedLayer.OS}, pkg) } - mergedLayer.Packages[i].Identifier.UID = calcPkgUID("", pkg) + mergedLayer.Packages[i].Identifier.UID = dependency.UID("", pkg) // Only debian packages if licenses, ok := dpkgLicenses[pkg.Name]; ok { @@ -244,7 +244,7 @@ func ApplyLayers(layers []ftypes.BlobInfo) ftypes.ArtifactDetail { if pkg.Identifier.PURL == nil { app.Packages[i].Identifier.PURL = newPURL(app.Type, types.Metadata{}, pkg) } - app.Packages[i].Identifier.UID = calcPkgUID(app.FilePath, pkg) + app.Packages[i].Identifier.UID = dependency.UID(app.FilePath, pkg) } } @@ -263,22 +263,6 @@ func newPURL(pkgType ftypes.TargetType, metadata types.Metadata, pkg ftypes.Pack return p.Unwrap() } -// calcPkgUID calculates the hash of the package for the unique ID -func calcPkgUID(filePath string, pkg ftypes.Package) string { - v := map[string]any{ - "filePath": filePath, // To differentiate the hash of the same package but different file path - "pkg": pkg, - } - hash, err := hashstructure.Hash(v, hashstructure.FormatV2, &hashstructure.HashOptions{ - ZeroNil: true, - IgnoreZeroValue: true, - }) - if err != nil { - log.Warn("Failed to calculate the package hash", log.String("pkg", pkg.Name), log.Err(err)) - } - return fmt.Sprintf("%x", hash) -} - // aggregate merges all packages installed by pip/gem/npm/jar/conda into each application func aggregate(detail *ftypes.ArtifactDetail) { var apps []ftypes.Application diff --git a/pkg/sbom/core/bom.go b/pkg/sbom/core/bom.go index 1fb3078d0c6b..51875bff8738 100644 --- a/pkg/sbom/core/bom.go +++ b/pkg/sbom/core/bom.go @@ -194,7 +194,6 @@ type Relationship struct { type Vulnerability struct { dtypes.Vulnerability ID string - PkgID string PkgName string InstalledVersion string FixedVersion string diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 9209c0c0100c..9dc28a2ab812 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -24,6 +24,46 @@ import ( "github.com/aquasecurity/trivy/pkg/uuid" ) +var ( + binutilsIdentifier = ftypes.PkgIdentifier{ + UID: "7CC457C23685235A", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeRPM, + Namespace: "centos", + Name: "binutils", + Version: "2.30-93.el8", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "aarch64", + }, + { + Key: "distro", + Value: "centos-8.3.2011", + }, + }, + }, + } + + actionpack700Identifier = ftypes.PkgIdentifier{ + UID: "DFF5FF40889105B2", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.0", + }, + } + + actionpack701Identifier = ftypes.PkgIdentifier{ + UID: "6B0A6392BAA7D584", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeGem, + Name: "actionpack", + Version: "7.0.1", + }, + } +) + func TestMarshaler_MarshalReport(t *testing.T) { testSBOM := core.NewBOM(core.Options{GenerateBOMRef: true}) testSBOM.AddComponent(&core.Component{ @@ -74,30 +114,13 @@ func TestMarshaler_MarshalReport(t *testing.T) { Type: ftypes.CentOS, Packages: []ftypes.Package{ { - ID: "binutils@2.30-93.el8", - Name: "binutils", - Version: "2.30", - Release: "93.el8", - Epoch: 0, - Arch: "aarch64", - Identifier: ftypes.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeRPM, - Namespace: "centos", - Name: "binutils", - Version: "2.30-93.el8", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "aarch64", - }, - { - Key: "distro", - Value: "centos-8.3.2011", - }, - }, - }, - }, + ID: "binutils@2.30-93.el8", + Name: "binutils", + Version: "2.30", + Release: "93.el8", + Epoch: 0, + Arch: "aarch64", + Identifier: binutilsIdentifier, SrcName: "binutils", SrcVersion: "2.30", SrcRelease: "93.el8", @@ -124,6 +147,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "Red Hat OVAL v2", URL: "https://www.redhat.com/security/data/oval/v2/", }, + PkgIdentifier: binutilsIdentifier, Vulnerability: dtypes.Vulnerability{ Title: "binutils: Use-after-free in the error function", Description: "In GNU Binutils 2.31.1, there is a use-after-free in the error function in elfcomm.c when called from the process_archive function in readelf.c via a crafted ELF file.", @@ -158,23 +182,18 @@ func TestMarshaler_MarshalReport(t *testing.T) { Packages: []ftypes.Package{ { // This package conflicts - ID: "actionpack@7.0.0", - Name: "actionpack", - Version: "7.0.0", - Identifier: ftypes.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, - }, - Indirect: false, + ID: "actionpack@7.0.0", + Name: "actionpack", + Version: "7.0.0", + Identifier: actionpack700Identifier, + Indirect: false, }, { ID: "actioncontroller@7.0.0", Name: "actioncontroller", Version: "7.0.0", Identifier: ftypes.PkgIdentifier{ + UID: "41ED2619CA718170", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGem, Name: "actioncontroller", @@ -195,16 +214,10 @@ func TestMarshaler_MarshalReport(t *testing.T) { Packages: []ftypes.Package{ { // This package conflicts - ID: "actionpack@7.0.0", - Name: "actionpack", - Version: "7.0.0", - Identifier: ftypes.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, - }, + ID: "actionpack@7.0.0", + Name: "actionpack", + Version: "7.0.0", + Identifier: actionpack700Identifier, }, }, }, @@ -218,6 +231,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "Newtonsoft.Json", Version: "9.0.1", Identifier: ftypes.PkgIdentifier{ + UID: "94AB97F672F97AFB", PURL: &packageurl.PackageURL{ Type: packageurl.TypeNuget, Name: "Newtonsoft.Json", @@ -236,6 +250,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "golang.org/x/crypto", Version: "v0.0.0-20210421170649-83a5a9bb288b", Identifier: ftypes.PkgIdentifier{ + UID: "B7183ED2CF7EB470", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "golang.org/x", @@ -698,6 +713,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Epoch: 1, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ + UID: "2FF7A09FA4E6AA2E", PURL: &packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "centos", @@ -738,6 +754,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Epoch: 0, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ + UID: "2DCAB94016E57F8E", PURL: &packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "centos", @@ -771,32 +788,20 @@ func TestMarshaler_MarshalReport(t *testing.T) { Type: ftypes.GemSpec, Packages: []ftypes.Package{ { - ID: "actionpack@7.0.0", - Name: "actionpack", - Version: "7.0.0", - Identifier: ftypes.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, - }, + ID: "actionpack@7.0.0", + Name: "actionpack", + Version: "7.0.0", + Identifier: actionpack700Identifier, Layer: ftypes.Layer{ DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488", }, FilePath: "tools/project-john/specifications/actionpack.gemspec", }, { - ID: "actionpack@7.0.1", - Name: "actionpack", - Version: "7.0.1", - Identifier: ftypes.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, - }, + ID: "actionpack@7.0.1", + Name: "actionpack", + Version: "7.0.1", + Identifier: actionpack701Identifier, Layer: ftypes.Layer{ DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488", }, @@ -805,17 +810,11 @@ func TestMarshaler_MarshalReport(t *testing.T) { }, Vulnerabilities: []types.DetectedVulnerability{ { - VulnerabilityID: "CVE-2022-23633", - PkgID: "actionpack@7.0.0", - PkgName: "actionpack", - PkgPath: "tools/project-john/specifications/actionpack.gemspec", - PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.0", - }, - }, + VulnerabilityID: "CVE-2022-23633", + PkgID: "actionpack@7.0.0", + PkgName: "actionpack", + PkgPath: "tools/project-john/specifications/actionpack.gemspec", + PkgIdentifier: actionpack700Identifier, InstalledVersion: "7.0.0", FixedVersion: "~> 5.2.6, >= 5.2.6.2, ~> 6.0.4, >= 6.0.4.6, ~> 6.1.4, >= 6.1.4.6, >= 7.0.2.2", SeveritySource: vulnerability.RubySec, @@ -855,17 +854,11 @@ func TestMarshaler_MarshalReport(t *testing.T) { }, }, { - VulnerabilityID: "CVE-2022-23633", - PkgID: "actionpack@7.0.1", - PkgName: "actionpack", - PkgPath: "tools/project-doe/specifications/actionpack.gemspec", - PkgIdentifier: ftypes.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeGem, - Name: "actionpack", - Version: "7.0.1", - }, - }, + VulnerabilityID: "CVE-2022-23633", + PkgID: "actionpack@7.0.1", + PkgName: "actionpack", + PkgPath: "tools/project-doe/specifications/actionpack.gemspec", + PkgIdentifier: actionpack701Identifier, InstalledVersion: "7.0.1", FixedVersion: "~> 5.2.6, >= 5.2.6.2, ~> 6.0.4, >= 6.0.4.6, ~> 6.1.4, >= 6.1.4.6, >= 7.0.2.2", SeveritySource: vulnerability.RubySec, @@ -1241,6 +1234,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "actioncable", Version: "6.1.4.1", Identifier: ftypes.PkgIdentifier{ + UID: "2E6CF0E3CD6949BD", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGem, Name: "actioncable", @@ -1259,6 +1253,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "org.springframework:spring-web", Version: "5.3.22", Identifier: ftypes.PkgIdentifier{ + UID: "38DDCC9B589D3124", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.springframework", @@ -1280,6 +1275,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "@babel/helper-string-parser", Version: "7.23.4", Identifier: ftypes.PkgIdentifier{ + UID: "F4C833D7F3FD9ECF", PURL: &packageurl.PackageURL{ Type: packageurl.TypeNPM, Namespace: "@babel", @@ -1458,6 +1454,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Version: "2.13.4.1", Identifier: ftypes.PkgIdentifier{ BOMRef: "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.4.1?file_path=jackson-databind-2.13.4.1.jar", + UID: "9A5066570222D04C", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "com.fasterxml.jackson.core", @@ -1475,6 +1472,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { PkgPath: "jackson-databind-2.13.4.1.jar", PkgIdentifier: ftypes.PkgIdentifier{ BOMRef: "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.4.1?file_path=jackson-databind-2.13.4.1.jar", + UID: "9A5066570222D04C", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "com.fasterxml.jackson.core", @@ -1641,6 +1639,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "org.apache.nifi:nifi-dbcp-base", Version: "1.20.0", Identifier: ftypes.PkgIdentifier{ + UID: "6F266C79E57ADC38", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.apache.nifi", @@ -1654,6 +1653,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "org.apache.nifi:nifi-hikari-dbcp-service", Version: "1.20.0", Identifier: ftypes.PkgIdentifier{ + UID: "3EA16F0A4CAB50F9", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.apache.nifi", @@ -1670,6 +1670,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { PkgName: "org.apache.nifi:nifi-dbcp-base", PkgPath: "nifi-dbcp-base-1.20.0.jar", PkgIdentifier: ftypes.PkgIdentifier{ + UID: "6F266C79E57ADC38", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.apache.nifi", @@ -1720,6 +1721,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { PkgName: "org.apache.nifi:nifi-hikari-dbcp-service", PkgPath: "nifi-hikari-dbcp-service-1.20.0.jar", PkgIdentifier: ftypes.PkgIdentifier{ + UID: "3EA16F0A4CAB50F9", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.apache.nifi", @@ -1939,6 +1941,7 @@ func TestMarshaler_MarshalReport(t *testing.T) { Name: "ruby-typeprof", Version: "0.20.1", Identifier: ftypes.PkgIdentifier{ + UID: "C861FD5FC7AC663F", PURL: &packageurl.PackageURL{ Type: packageurl.TypeNPM, Name: "ruby-typeprof", diff --git a/pkg/sbom/io/encode.go b/pkg/sbom/io/encode.go index 9672f1648dc6..64a24dbdcb07 100644 --- a/pkg/sbom/io/encode.go +++ b/pkg/sbom/io/encode.go @@ -174,25 +174,33 @@ func (e *Encoder) encodePackages(parent *core.Component, result types.Result) { vulns := make(map[string][]core.Vulnerability) for _, vuln := range result.Vulnerabilities { v := e.vulnerability(vuln) - vulns[v.PkgID] = append(vulns[v.PkgID], v) + vulns[vuln.PkgIdentifier.UID] = append(vulns[vuln.PkgIdentifier.UID], v) } // Convert packages into components and add them to the BOM parentRelationship := core.RelationshipContains + + // UID => Package Component components := make(map[string]*core.Component, len(result.Packages)) + // PkgID => Package Component + dependencies := make(map[string]*core.Component, len(result.Packages)) for i, pkg := range result.Packages { pkgID := lo.Ternary(pkg.ID == "", fmt.Sprintf("%s@%s", pkg.Name, pkg.Version), pkg.ID) result.Packages[i].ID = pkgID // Convert packages to components c := e.component(result, pkg) - components[pkgID+pkg.FilePath] = c + components[pkg.Identifier.UID] = c + + // For dependencies: the key "pkgID" might be duplicated in aggregated packages, + // but it doesn't matter as they don't have "DependsOn". + dependencies[pkgID] = c // Add a component e.bom.AddComponent(c) // Add vulnerabilities - if vv := vulns[pkgID]; vv != nil { + if vv := vulns[pkg.Identifier.UID]; vv != nil { e.bom.AddVulnerabilities(c, vv) } @@ -211,7 +219,7 @@ func (e *Encoder) encodePackages(parent *core.Component, result types.Result) { if pkg.Relationship == ftypes.RelationshipRoot { continue } - c := components[pkg.ID+pkg.FilePath] + c := components[pkg.Identifier.UID] // Add a relationship between the parent and the package if needed if e.belongToParent(pkg, parents) { @@ -220,7 +228,7 @@ func (e *Encoder) encodePackages(parent *core.Component, result types.Result) { // Add relationships between the package and its dependencies for _, dep := range pkg.DependsOn { - dependsOn, ok := components[dep] + dependsOn, ok := dependencies[dep] if !ok { continue } @@ -369,7 +377,6 @@ func (*Encoder) vulnerability(vuln types.DetectedVulnerability) core.Vulnerabili return core.Vulnerability{ Vulnerability: vuln.Vulnerability, ID: vuln.VulnerabilityID, - PkgID: lo.Ternary(vuln.PkgID == "", fmt.Sprintf("%s@%s", vuln.PkgName, vuln.InstalledVersion), vuln.PkgID), PkgName: vuln.PkgName, InstalledVersion: vuln.InstalledVersion, FixedVersion: vuln.FixedVersion, diff --git a/pkg/sbom/io/encode_test.go b/pkg/sbom/io/encode_test.go index d165b64c3e80..06109c963d4f 100644 --- a/pkg/sbom/io/encode_test.go +++ b/pkg/sbom/io/encode_test.go @@ -55,6 +55,7 @@ func TestEncoder_Encode(t *testing.T) { Name: "libc6", Version: "2.37-15.1", Identifier: ftypes.PkgIdentifier{ + UID: "33654D2C483FC3AD", PURL: &packageurl.PackageURL{ Type: packageurl.TypeDebian, Name: "libc6", @@ -67,6 +68,7 @@ func TestEncoder_Encode(t *testing.T) { Name: "curl", Version: "7.50.3-1", Identifier: ftypes.PkgIdentifier{ + UID: "51BA9E006222819D", PURL: &packageurl.PackageURL{ Type: packageurl.TypeDebian, Name: "curl", @@ -88,6 +90,9 @@ func TestEncoder_Encode(t *testing.T) { Vulnerability: dtypes.Vulnerability{ Severity: "HIGH", }, + PkgIdentifier: ftypes.PkgIdentifier{ + UID: "51BA9E006222819D", + }, }, }, }, @@ -97,20 +102,66 @@ func TestEncoder_Encode(t *testing.T) { Class: types.ClassLangPkg, Packages: []ftypes.Package{ { - ID: "org.apache.xmlgraphics/batik-anim:1.9.1", - Name: "org.apache.xmlgraphics/batik-anim", - Version: "1.9.1", - FilePath: "/app/batik-anim-1.9.1.jar", + ID: "com.fasterxml.jackson.core:jackson-databind:2.13.4", + Name: "com.fasterxml.jackson.core:jackson-databind", + Version: "2.13.4", + FilePath: "/foo/jackson-databind-2.13.4.jar", Identifier: ftypes.PkgIdentifier{ + UID: "A6BD5A2FE5C00E10", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, - Namespace: "org.apache.xmlgraphics", - Name: "batik-anim", - Version: "1.9.1", + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.13.4", + }, + }, + }, + { + ID: "com.fasterxml.jackson.core:jackson-databind:2.13.4", + Name: "com.fasterxml.jackson.core:jackson-databind", + Version: "2.13.4", + FilePath: "/bar/jackson-databind-2.13.4.jar", + Identifier: ftypes.PkgIdentifier{ + UID: "64244651208EC759", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.13.4", }, }, }, }, + Vulnerabilities: []types.DetectedVulnerability{ + { + PkgName: "com.fasterxml.jackson.core:jackson-databind", + PkgID: "com.fasterxml.jackson.core:jackson-databind:2.13.4", + VulnerabilityID: "CVE-2022-42003", + InstalledVersion: "2.13.4", + FixedVersion: "2.12.7.1, 2.13.4.2", + PkgPath: "/foo/jackson-databind-2.13.4.jar", + Vulnerability: dtypes.Vulnerability{ + Severity: "HIGH", + }, + PkgIdentifier: ftypes.PkgIdentifier{ + UID: "A6BD5A2FE5C00E10", + }, + }, + { + PkgName: "com.fasterxml.jackson.core:jackson-databind", + PkgID: "com.fasterxml.jackson.core:jackson-databind:2.13.4", + VulnerabilityID: "CVE-2022-42003", + InstalledVersion: "2.13.4", + FixedVersion: "2.12.7.1, 2.13.4.2", + PkgPath: "/bar/jackson-databind-2.13.4.jar", + Vulnerability: dtypes.Vulnerability{ + Severity: "HIGH", + }, + PkgIdentifier: ftypes.PkgIdentifier{ + UID: "64244651208EC759", + }, + }, + }, }, }, }, @@ -185,6 +236,7 @@ func TestEncoder_Encode(t *testing.T) { }, }, PkgIdentifier: ftypes.PkgIdentifier{ + UID: "33654D2C483FC3AD", PURL: &packageurl.PackageURL{ Type: packageurl.TypeDebian, Name: "libc6", @@ -208,6 +260,7 @@ func TestEncoder_Encode(t *testing.T) { }, }, PkgIdentifier: ftypes.PkgIdentifier{ + UID: "51BA9E006222819D", PURL: &packageurl.PackageURL{ Type: packageurl.TypeDebian, Name: "curl", @@ -218,22 +271,22 @@ func TestEncoder_Encode(t *testing.T) { }, uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"): { Type: core.TypeLibrary, - Group: "org.apache.xmlgraphics", - Name: "batik-anim", - Version: "1.9.1", + Group: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.13.4", Files: []core.File{ { - Path: "/app/batik-anim-1.9.1.jar", + Path: "/foo/jackson-databind-2.13.4.jar", }, }, Properties: []core.Property{ { Name: core.PropertyFilePath, - Value: "/app/batik-anim-1.9.1.jar", + Value: "/foo/jackson-databind-2.13.4.jar", }, { Name: core.PropertyPkgID, - Value: "org.apache.xmlgraphics/batik-anim:1.9.1", + Value: "com.fasterxml.jackson.core:jackson-databind:2.13.4", }, { Name: core.PropertyPkgType, @@ -241,13 +294,49 @@ func TestEncoder_Encode(t *testing.T) { }, }, PkgIdentifier: ftypes.PkgIdentifier{ + UID: "A6BD5A2FE5C00E10", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, - Namespace: "org.apache.xmlgraphics", - Name: "batik-anim", - Version: "1.9.1", + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.13.4", }, - BOMRef: "pkg:maven/org.apache.xmlgraphics/batik-anim@1.9.1", + BOMRef: "3ff14136-e09f-4df9-80ea-000000000005", + }, + }, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"): { + Type: core.TypeLibrary, + Group: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.13.4", + Files: []core.File{ + { + Path: "/bar/jackson-databind-2.13.4.jar", + }, + }, + Properties: []core.Property{ + { + Name: core.PropertyFilePath, + Value: "/bar/jackson-databind-2.13.4.jar", + }, + { + Name: core.PropertyPkgID, + Value: "com.fasterxml.jackson.core:jackson-databind:2.13.4", + }, + { + Name: core.PropertyPkgType, + Value: "jar", + }, + }, + PkgIdentifier: ftypes.PkgIdentifier{ + UID: "64244651208EC759", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "com.fasterxml.jackson.core", + Name: "jackson-databind", + Version: "2.13.4", + }, + BOMRef: "3ff14136-e09f-4df9-80ea-000000000006", }, }, }, @@ -261,6 +350,10 @@ func TestEncoder_Encode(t *testing.T) { Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"), Type: core.RelationshipContains, }, + { + Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"), + Type: core.RelationshipContains, + }, }, uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): { { @@ -280,12 +373,12 @@ func TestEncoder_Encode(t *testing.T) { }, }, uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"): nil, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"): nil, }, wantVulns: map[uuid.UUID][]core.Vulnerability{ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000004"): { { ID: "CVE-2021-22876", - PkgID: "curl@7.50.3-1", PkgName: "curl", InstalledVersion: "7.50.3-1", FixedVersion: "7.50.3-1+deb9u1", @@ -294,6 +387,28 @@ func TestEncoder_Encode(t *testing.T) { }, }, }, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"): { + { + ID: "CVE-2022-42003", + PkgName: "com.fasterxml.jackson.core:jackson-databind", + InstalledVersion: "2.13.4", + FixedVersion: "2.12.7.1, 2.13.4.2", + Vulnerability: dtypes.Vulnerability{ + Severity: "HIGH", + }, + }, + }, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"): { + { + ID: "CVE-2022-42003", + PkgName: "com.fasterxml.jackson.core:jackson-databind", + InstalledVersion: "2.13.4", + FixedVersion: "2.12.7.1, 2.13.4.2", + Vulnerability: dtypes.Vulnerability{ + Severity: "HIGH", + }, + }, + }, }, }, { @@ -312,6 +427,7 @@ func TestEncoder_Encode(t *testing.T) { ID: "github.com/org/root", Name: "github.com/org/root", Identifier: ftypes.PkgIdentifier{ + UID: "03D528806D964D22", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -328,6 +444,7 @@ func TestEncoder_Encode(t *testing.T) { Name: "github.com/org/direct", Version: "v1.0.0", Identifier: ftypes.PkgIdentifier{ + UID: "A74CADAD4D9805FF", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -345,6 +462,7 @@ func TestEncoder_Encode(t *testing.T) { Name: "github.com/org/indirect", Version: "2.0.0", Identifier: ftypes.PkgIdentifier{ + UID: "955AB4E7E24AC085", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -359,6 +477,7 @@ func TestEncoder_Encode(t *testing.T) { Name: "stdlib", Version: "1.22.1", Identifier: ftypes.PkgIdentifier{ + UID: "49728B9674E318A6", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Name: "stdlib", @@ -418,6 +537,7 @@ func TestEncoder_Encode(t *testing.T) { }, }, PkgIdentifier: ftypes.PkgIdentifier{ + UID: "03D528806D964D22", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -442,6 +562,7 @@ func TestEncoder_Encode(t *testing.T) { }, }, PkgIdentifier: ftypes.PkgIdentifier{ + UID: "A74CADAD4D9805FF", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -467,6 +588,7 @@ func TestEncoder_Encode(t *testing.T) { }, }, PkgIdentifier: ftypes.PkgIdentifier{ + UID: "955AB4E7E24AC085", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "github.com/org", @@ -492,6 +614,7 @@ func TestEncoder_Encode(t *testing.T) { }, }, PkgIdentifier: ftypes.PkgIdentifier{ + UID: "49728B9674E318A6", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Name: "stdlib", @@ -552,6 +675,7 @@ func TestEncoder_Encode(t *testing.T) { Name: "org.apache.logging.log4j:log4j-core", Version: "2.23.1", Identifier: ftypes.PkgIdentifier{ + UID: "6C0AE96901617503", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.apache.logging.log4j", @@ -598,6 +722,7 @@ func TestEncoder_Encode(t *testing.T) { Name: "org.apache.logging.log4j:log4j-core", Version: "2.23.1", Identifier: ftypes.PkgIdentifier{ + UID: "6C0AE96901617503", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, Namespace: "org.apache.logging.log4j", @@ -698,6 +823,7 @@ var ( Group: "org.apache.logging.log4j", Version: "2.23.1", PkgIdentifier: ftypes.PkgIdentifier{ + UID: "6C0AE96901617503", BOMRef: "pkg:maven/org.apache.logging.log4j/log4j-core@2.23.1", PURL: &packageurl.PackageURL{ Type: packageurl.TypeMaven, diff --git a/pkg/sbom/spdx/marshal_test.go b/pkg/sbom/spdx/marshal_test.go index 02585ceaa418..122e529c14d5 100644 --- a/pkg/sbom/spdx/marshal_test.go +++ b/pkg/sbom/spdx/marshal_test.go @@ -64,6 +64,7 @@ func TestMarshaler_Marshal(t *testing.T) { Epoch: 0, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ + UID: "F4C10A4371C93487", PURL: &packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "centos", @@ -101,6 +102,7 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ + UID: "B1A9DE534F2737AF", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGem, Name: "actionpack", @@ -112,6 +114,7 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actioncontroller", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ + UID: "1628B51BD543965D", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGem, Name: "actioncontroller", @@ -130,6 +133,7 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ + UID: "92D6B6D3FF6F8FF5", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGem, Name: "actionpack", @@ -387,6 +391,7 @@ func TestMarshaler_Marshal(t *testing.T) { Epoch: 1, Arch: "aarch64", Identifier: ftypes.PkgIdentifier{ + UID: "740219943F17B1DF", PURL: &packageurl.PackageURL{ Type: packageurl.TypeRPM, Namespace: "centos", @@ -427,6 +432,7 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ + UID: "E8DB2C6E35F8B990", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGem, Name: "actionpack", @@ -443,6 +449,7 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "actionpack", Version: "7.0.1", Identifier: ftypes.PkgIdentifier{ + UID: "B3E70B2159CFAC50", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGem, Name: "actionpack", @@ -1063,6 +1070,7 @@ func TestMarshaler_Marshal(t *testing.T) { Name: "golang.org/x/crypto", Version: "v0.0.1", Identifier: ftypes.PkgIdentifier{ + UID: "161541A259EF014B", PURL: &packageurl.PackageURL{ Type: packageurl.TypeGolang, Namespace: "golang.org/x",