From 89c419091483d8f4f5e83a046dd0b45aaaba3eb5 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Mon, 12 Aug 2024 12:20:46 -0400 Subject: [PATCH] do not fail when inflating DB records (#2049) Signed-off-by: Alex Goodman --- grype/db/vulnerability_provider.go | 12 ++++++---- grype/db/vulnerability_provider_mocks_test.go | 23 +++++++++++++++++-- grype/db/vulnerability_provider_test.go | 5 ++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/grype/db/vulnerability_provider.go b/grype/db/vulnerability_provider.go index faff3264016..3453eb38750 100644 --- a/grype/db/vulnerability_provider.go +++ b/grype/db/vulnerability_provider.go @@ -52,7 +52,8 @@ func (pr *VulnerabilityProvider) Get(id, namespace string) ([]vulnerability.Vuln for _, vuln := range vulns { vulnObj, err := vulnerability.NewVulnerability(vuln) if err != nil { - return nil, fmt.Errorf("provider failed to inflate vulnerability record (namespace=%q id=%q): %w", vuln.Namespace, vuln.ID, err) + log.WithFields("namespace", vuln.Namespace, "id", vuln.ID).Errorf("failed to inflate vulnerability record: %v", err) + continue } results = append(results, *vulnObj) @@ -87,7 +88,8 @@ func (pr *VulnerabilityProvider) GetByDistro(d *distro.Distro, p pkg.Package) ([ for _, vuln := range allPkgVulns { vulnObj, err := vulnerability.NewVulnerability(vuln) if err != nil { - return nil, fmt.Errorf("provider failed to inflate vulnerability record (namespace=%q id=%q distro=%q): %w", vuln.Namespace, vuln.ID, d, err) + log.WithFields("namespace", vuln.Namespace, "id", vuln.ID).Errorf("failed to inflate vulnerability record (by distro): %v", err) + continue } vulnerabilities = append(vulnerabilities, *vulnObj) @@ -121,7 +123,8 @@ func (pr *VulnerabilityProvider) GetByLanguage(l syftPkg.Language, p pkg.Package for _, vuln := range allPkgVulns { vulnObj, err := vulnerability.NewVulnerability(vuln) if err != nil { - return nil, fmt.Errorf("provider failed to inflate vulnerability record (namespace=%q id=%q language=%q): %w", vuln.Namespace, vuln.ID, l, err) + log.WithFields("namespace", vuln.Namespace, "id", vuln.ID).Errorf("failed to inflate vulnerability record (by language): %v", err) + continue } vulnerabilities = append(vulnerabilities, *vulnObj) @@ -169,7 +172,8 @@ func (pr *VulnerabilityProvider) GetByCPE(requestCPE cpe.CPE) ([]vulnerability.V if len(candidateMatchCpes) > 0 { vulnObj, err := vulnerability.NewVulnerability(vuln) if err != nil { - return nil, fmt.Errorf("provider failed to inflate vulnerability record (namespace=%q id=%q cpe=%q): %w", vuln.Namespace, vuln.ID, requestCPE.Attributes.BindToFmtString(), err) + log.WithFields("namespace", vuln.Namespace, "id", vuln.ID, "cpe", requestCPE.Attributes.BindToFmtString()).Errorf("failed to inflate vulnerability record (by CPE): %v", err) + continue } vulnObj.CPEs = candidateMatchCpes diff --git a/grype/db/vulnerability_provider_mocks_test.go b/grype/db/vulnerability_provider_mocks_test.go index 06db793b469..a4704156240 100644 --- a/grype/db/vulnerability_provider_mocks_test.go +++ b/grype/db/vulnerability_provider_mocks_test.go @@ -31,6 +31,14 @@ func (d *mockStore) stub() { ID: "CVE-2013-fake-2", VersionFormat: "deb", }, + // poison the well! this is not a valid entry, but we want the matching process to survive and find other good results... + { + PackageName: "neutron", + Namespace: "debian:distro:debian:8", + VersionConstraint: "< 70.3.0-rc0", // intentionally bad value + ID: "CVE-2014-fake-3", + VersionFormat: "apk", + }, }, } d.data["nvd:cpe"] = map[string][]grypeDB.Vulnerability{ @@ -62,7 +70,7 @@ func (d *mockStore) stub() { ID: "CVE-2014-fake-5", VersionFormat: "unknown", CPEs: []string{ - "cpe:2.3:*:couldntgetthisrightcouldyou:activerecord:4.0.1:*:*:*:*:*:*:*", + "cpe:2.3:*:couldntgetthisrightcouldyou:activerecord:4.0.1:*:*:*:*:*:*:*", // shouldn't match on this }, }, { @@ -72,7 +80,18 @@ func (d *mockStore) stub() { ID: "CVE-2014-fake-6", VersionFormat: "unknown", CPEs: []string{ - "cpe:2.3:*:awesome:awesome:*:*:*:*:*:*:*:*", + "cpe:2.3:*:awesome:awesome:*:*:*:*:*:*:*:*", // shouldn't match on this + }, + }, + // poison the well! this is not a valid entry, but we want the matching process to survive and find other good results... + { + PackageName: "activerecord", + Namespace: "nvd:cpe", + VersionConstraint: "< 70.3.0-rc0", // intentionally bad value + ID: "CVE-2014-fake-7", + VersionFormat: "apk", + CPEs: []string{ + "cpe:2.3:*:activerecord:activerecord:*:*:*:*:*:rails:*:*", }, }, }, diff --git a/grype/db/vulnerability_provider_test.go b/grype/db/vulnerability_provider_test.go index 26163b8fdf3..cd3f5e6e65c 100644 --- a/grype/db/vulnerability_provider_test.go +++ b/grype/db/vulnerability_provider_test.go @@ -198,4 +198,9 @@ func Test_Get(t *testing.T) { t.Errorf("diff: %+v", d) } } + + // prove we survive a bad request + actual, err = provider.Get("CVE-2014-fake-3", "debian:distro:debian:8") + require.NoError(t, err) + assert.Empty(t, actual) }