From cfabdf9138d95f61bb7c40655e9c11acfe00797b Mon Sep 17 00:00:00 2001 From: gmetaxo Date: Thu, 15 Dec 2022 19:21:54 +0200 Subject: [PATCH] fix(vuln): include duplicate vulnerabilities with different package paths in the final report (#3275) * Add test for filter with both duplicates and different package paths * Add package path in key of uniqVulns map * Add package path to the sorting logic --- pkg/result/filter.go | 2 +- pkg/result/filter_test.go | 133 +++++++++++++++++++++++++++++++++++++ pkg/types/vulnerability.go | 7 +- 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/pkg/result/filter.go b/pkg/result/filter.go index 668e29bd312..f9b8bb3ec5f 100644 --- a/pkg/result/filter.go +++ b/pkg/result/filter.go @@ -74,7 +74,7 @@ func filterVulnerabilities(vulns []types.DetectedVulnerability, severities []dbT } // Check if there is a duplicate vulnerability - key := fmt.Sprintf("%s/%s/%s", vuln.VulnerabilityID, vuln.PkgName, vuln.InstalledVersion) + key := fmt.Sprintf("%s/%s/%s/%s", vuln.VulnerabilityID, vuln.PkgName, vuln.InstalledVersion, vuln.PkgPath) if old, ok := uniqVulns[key]; ok && !shouldOverwrite(old, vuln) { continue } diff --git a/pkg/result/filter_test.go b/pkg/result/filter_test.go index fa6dae8a963..a352eeff82a 100644 --- a/pkg/result/filter_test.go +++ b/pkg/result/filter_test.go @@ -502,6 +502,139 @@ func TestClient_Filter(t *testing.T) { }, }, }, + { + name: "happy path with duplicates and different package paths", + args: args{ + result: types.Result{ + Vulnerabilities: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2019-0001", + PkgPath: "some/path/a.jar", + PkgName: "bar", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityCritical.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0001", + PkgPath: "some/other/path/a.jar", + PkgName: "bar", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityCritical.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0002", + PkgName: "baz", + PkgPath: "some/path/b.jar", + InstalledVersion: "1.2.3", + FixedVersion: "", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityHigh.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0002", + PkgPath: "some/path/b.jar", + PkgName: "baz", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityHigh.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0003", + PkgPath: "some/path/c.jar", + PkgName: "bar", + InstalledVersion: "1.2.3", + FixedVersion: "", + Vulnerability: dbTypes.Vulnerability{ + Severity: "", + }, + }, + { + VulnerabilityID: "CVE-2019-0003", + PkgName: "bar", + PkgPath: "some/path/c.jar", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: "", + }, + }, + { + VulnerabilityID: "CVE-2019-0003", + PkgName: "bar", + PkgPath: "some/other/path/c.jar", + InstalledVersion: "1.2.3", + FixedVersion: "", + Vulnerability: dbTypes.Vulnerability{ + Severity: "", + }, + }, + }, + }, + severities: []dbTypes.Severity{dbTypes.SeverityCritical, dbTypes.SeverityHigh, dbTypes.SeverityUnknown}, + ignoreUnfixed: false, + }, + wantVulns: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2019-0001", + PkgPath: "some/other/path/a.jar", + PkgName: "bar", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityCritical.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0001", + PkgPath: "some/path/a.jar", + PkgName: "bar", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityCritical.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0003", + PkgName: "bar", + PkgPath: "some/other/path/c.jar", + InstalledVersion: "1.2.3", + FixedVersion: "", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityUnknown.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0003", + PkgName: "bar", + PkgPath: "some/path/c.jar", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityUnknown.String(), + }, + }, + { + VulnerabilityID: "CVE-2019-0002", + PkgPath: "some/path/b.jar", + PkgName: "baz", + InstalledVersion: "1.2.3", + FixedVersion: "1.2.4", + Vulnerability: dbTypes.Vulnerability{ + Severity: dbTypes.SeverityHigh.String(), + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/types/vulnerability.go b/pkg/types/vulnerability.go index b8b0057d29d..18acd4fd868 100644 --- a/pkg/types/vulnerability.go +++ b/pkg/types/vulnerability.go @@ -40,7 +40,7 @@ type BySeverity []DetectedVulnerability // Len returns the length of DetectedVulnerabilities func (v BySeverity) Len() int { return len(v) } -// Less compares 2 DetectedVulnerabilities based on package name, severity and vulnerabilityID +// Less compares 2 DetectedVulnerabilities based on package name, severity, vulnerabilityID and package path func (v BySeverity) Less(i, j int) bool { if v[i].PkgName != v[j].PkgName { return v[i].PkgName < v[j].PkgName @@ -53,7 +53,10 @@ func (v BySeverity) Less(i, j int) bool { if ret != 0 { return ret > 0 } - return v[i].VulnerabilityID < v[j].VulnerabilityID + if v[i].VulnerabilityID != v[j].VulnerabilityID { + return v[i].VulnerabilityID < v[j].VulnerabilityID + } + return v[i].PkgPath < v[j].PkgPath } // Swap swaps 2 vulnerability