From 642bcbc76d4074e501f9e1e2567f1599356e26a7 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Mon, 18 Dec 2023 16:29:39 +0600 Subject: [PATCH 1/2] refactor(cyclonedx): use filepath to group pkgs and vulns --- pkg/sbom/cyclonedx/marshal.go | 10 +++- pkg/sbom/cyclonedx/marshal_test.go | 81 +++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index c6934571c0a0..3ff4cd20e564 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -144,12 +144,20 @@ func (e *Marshaler) marshalPackages(metadata types.Metadata, result types.Result // Group vulnerabilities by package ID vulns := lo.GroupBy(result.Vulnerabilities, func(v types.DetectedVulnerability) string { - return lo.Ternary(v.PkgID == "", fmt.Sprintf("%s@%s", v.PkgName, v.InstalledVersion), v.PkgID) + pkgID := lo.Ternary(v.PkgID == "", fmt.Sprintf("%s@%s", v.PkgName, v.InstalledVersion), v.PkgID) + if v.PkgPath != "" { + pkgID = fmt.Sprintf("%s@%s", pkgID, v.PkgPath) + } + return pkgID }) // Create package map pkgs := lo.SliceToMap(result.Packages, func(pkg ftypes.Package) (string, Package) { pkgID := lo.Ternary(pkg.ID == "", fmt.Sprintf("%s@%s", pkg.Name, utils.FormatVersion(pkg)), pkg.ID) + // To avoid skip same packages with different paths + if pkg.FilePath != "" { + pkgID = fmt.Sprintf("%s@%s", pkgID, pkg.FilePath) + } return pkgID, Package{ Type: result.Type, Metadata: metadata, diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 59f77a24ad63..95f03a2fb601 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -1190,7 +1190,7 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, { - name: "happy path. 2 packages for 1 CVE", + name: "happy path. Multiple packages for 1 CVE (2 same packages from different dirs and 1 package with a different name)", inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "CVE-2023-34468", @@ -1211,6 +1211,11 @@ func TestMarshaler_Marshal(t *testing.T) { Version: "1.20.0", FilePath: "nifi-hikari-dbcp-service-1.20.0.jar", }, + { + Name: "org.apache.nifi:nifi-hikari-dbcp-service", + Version: "1.20.0", + FilePath: "dir/nifi-hikari-dbcp-service-1.20.0.jar", + }, }, Vulnerabilities: []types.DetectedVulnerability{ { @@ -1255,6 +1260,48 @@ func TestMarshaler_Marshal(t *testing.T) { LastModifiedDate: lo.ToPtr(time.Date(2023, 6, 21, 02, 20, 0, 0, time.UTC)), }, }, + { + VulnerabilityID: "CVE-2023-34468", + PkgName: "org.apache.nifi:nifi-hikari-dbcp-service", + PkgPath: "dir/nifi-hikari-dbcp-service-1.20.0.jar", + InstalledVersion: "1.20.0", + FixedVersion: "1.22.0", + SeveritySource: vulnerability.GHSA, + PrimaryURL: "https://avd.aquasec.com/nvd/cve-2023-34468", + DataSource: &dtypes.DataSource{ + ID: vulnerability.GHSA, + Name: "GitHub Security Advisory Maven", + URL: "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Amaven", + }, + Vulnerability: dtypes.Vulnerability{ + Title: "Apache NiFi vulnerable to Code Injection", + Description: "The DBCPConnectionPool and HikariCPConnectionPool Controller Services in Apache NiFi 0.0.2 through 1.21.0...", + Severity: dtypes.SeverityHigh.String(), + CweIDs: []string{ + "CWE-94", + }, + VendorSeverity: dtypes.VendorSeverity{ + vulnerability.GHSA: dtypes.SeverityHigh, + vulnerability.NVD: dtypes.SeverityHigh, + }, + CVSS: dtypes.VendorCVSS{ + vulnerability.GHSA: dtypes.CVSS{ + V3Vector: "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + V3Score: 8.8, + }, + vulnerability.NVD: dtypes.CVSS{ + V3Vector: "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H", + V3Score: 8.8, + }, + }, + References: []string{ + "http://www.openwall.com/lists/oss-security/2023/06/12/3", + "https://github.com/advisories/GHSA-xm2m-2q6h-22jw", + }, + PublishedDate: lo.ToPtr(time.Date(2023, 6, 12, 16, 15, 0, 0, time.UTC)), + LastModifiedDate: lo.ToPtr(time.Date(2023, 6, 21, 02, 20, 0, 0, time.UTC)), + }, + }, { VulnerabilityID: "CVE-2023-34468", PkgName: "org.apache.nifi:nifi-hikari-dbcp-service", @@ -1348,6 +1395,24 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, }, + { + BOMRef: "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=dir%2Fnifi-hikari-dbcp-service-1.20.0.jar", + Type: "library", + Name: "nifi-hikari-dbcp-service", + Group: "org.apache.nifi", + Version: "1.20.0", + PackageURL: "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0", + Properties: &[]cdx.Property{ + { + Name: "aquasecurity:trivy:FilePath", + Value: "dir/nifi-hikari-dbcp-service-1.20.0.jar", + }, + { + Name: "aquasecurity:trivy:PkgType", + Value: "jar", + }, + }, + }, { BOMRef: "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=nifi-hikari-dbcp-service-1.20.0.jar", Type: "library", @@ -1372,6 +1437,7 @@ func TestMarshaler_Marshal(t *testing.T) { Ref: "3ff14136-e09f-4df9-80ea-000000000002", Dependencies: &[]string{ "pkg:maven/org.apache.nifi/nifi-dbcp-base@1.20.0?file_path=nifi-dbcp-base-1.20.0.jar", + "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=dir%2Fnifi-hikari-dbcp-service-1.20.0.jar", "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=nifi-hikari-dbcp-service-1.20.0.jar", }, }, @@ -1379,6 +1445,10 @@ func TestMarshaler_Marshal(t *testing.T) { Ref: "pkg:maven/org.apache.nifi/nifi-dbcp-base@1.20.0?file_path=nifi-dbcp-base-1.20.0.jar", Dependencies: lo.ToPtr([]string{}), }, + { + Ref: "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=dir%2Fnifi-hikari-dbcp-service-1.20.0.jar", + Dependencies: lo.ToPtr([]string{}), + }, { Ref: "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=nifi-hikari-dbcp-service-1.20.0.jar", Dependencies: lo.ToPtr([]string{}), @@ -1437,6 +1507,15 @@ func TestMarshaler_Marshal(t *testing.T) { }, }, }, + { + Ref: "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=dir%2Fnifi-hikari-dbcp-service-1.20.0.jar", + Range: &[]cdx.AffectedVersions{ + { + Version: "1.20.0", + Status: cdx.VulnerabilityStatusAffected, + }, + }, + }, { Ref: "pkg:maven/org.apache.nifi/nifi-hikari-dbcp-service@1.20.0?file_path=nifi-hikari-dbcp-service-1.20.0.jar", Range: &[]cdx.AffectedVersions{ From cba10b3c11b1d9aa96907694392fa836692cce65 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Tue, 19 Dec 2023 11:11:40 +0600 Subject: [PATCH 2/2] refactor: update comment --- pkg/sbom/cyclonedx/marshal.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index 3ff4cd20e564..e5c96fef60bc 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -154,7 +154,8 @@ func (e *Marshaler) marshalPackages(metadata types.Metadata, result types.Result // Create package map pkgs := lo.SliceToMap(result.Packages, func(pkg ftypes.Package) (string, Package) { pkgID := lo.Ternary(pkg.ID == "", fmt.Sprintf("%s@%s", pkg.Name, utils.FormatVersion(pkg)), pkg.ID) - // To avoid skip same packages with different paths + // To avoid merge same packages with different paths. + // Only ftypes.NodePkg, ftypes.PythonPkg, ftypes.GemSpec, ftypes.Jar, ftypes.CondaPkg use FilePath. if pkg.FilePath != "" { pkgID = fmt.Sprintf("%s@%s", pkgID, pkg.FilePath) }