Skip to content

Commit 848fb42

Browse files
committed
fix deprecated VulnerabilityMetadata with direct references since m.vulnerability now contains the metadata
Signed-off-by: Kyle Steere <[email protected]>
1 parent 38df837 commit 848fb42

File tree

3 files changed

+279
-31
lines changed

3 files changed

+279
-31
lines changed

pkg/scan/apk.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,10 +353,7 @@ func (s *Scanner) APKSBOM(ctx context.Context, ssbom *sbomSyft.SBOM) (*Result, e
353353
continue
354354
}
355355

356-
finding, err := mapMatchToFinding(m, s.vulnProvider)
357-
if err != nil {
358-
return nil, fmt.Errorf("failed to map match to finding: %w", err)
359-
}
356+
finding := mapMatchToFinding(m)
360357
if finding == nil {
361358
return nil, fmt.Errorf("failed to map match to finding: nil")
362359
}

pkg/scan/finding.go

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package scan
22

33
import (
4-
"fmt"
54
"sort"
65
"strings"
76

@@ -84,36 +83,16 @@ type TriageAssessment struct {
8483
Reason string
8584
}
8685

87-
func mapMatchToFinding(m match.Match, vulnProvider vulnerability.Provider) (*Finding, error) {
88-
metadata, err := vulnProvider.VulnerabilityMetadata(m.Vulnerability.Reference)
89-
if err != nil {
90-
return nil, fmt.Errorf("retrieving metadata for vulnerability %s (%s): %w", m.Vulnerability.ID, m.Vulnerability.Namespace, err)
91-
}
92-
93-
var relatedMetadatas []*vulnerability.Metadata
94-
for _, relatedRef := range m.Vulnerability.RelatedVulnerabilities {
95-
relatedMetadata, err := vulnProvider.VulnerabilityMetadata(relatedRef)
96-
if err != nil {
97-
return nil, fmt.Errorf("retrieving metadata for related vulnerability %s (%s): %w", relatedRef.ID, relatedRef.Namespace, err)
98-
}
99-
if relatedMetadata == nil {
100-
continue
101-
}
102-
relatedMetadatas = append(relatedMetadatas, relatedMetadata)
103-
}
104-
86+
func mapMatchToFinding(m match.Match) *Finding {
10587
var aliases []string
106-
for _, rel := range relatedMetadatas {
107-
if rel == nil {
108-
continue
109-
}
110-
if rel.ID == m.Vulnerability.ID {
88+
for _, relatedRef := range m.Vulnerability.RelatedVulnerabilities {
89+
if relatedRef.ID == m.Vulnerability.ID {
11190
// Don't count the matched vulnerability ID as its own alias. In v0.88.0, Grype
11291
// began listing vulnerabilities as their own related vulnerabilities, and we
11392
// filed a bug here: https://github.com/anchore/grype/issues/2514
11493
continue
11594
}
116-
aliases = append(aliases, rel.ID)
95+
aliases = append(aliases, relatedRef.ID)
11796
}
11897

11998
// Filter locations to only include those marked as "primary evidence"
@@ -141,13 +120,13 @@ func mapMatchToFinding(m match.Match, vulnProvider vulnerability.Provider) (*Fin
141120
},
142121
Vulnerability: Vulnerability{
143122
ID: m.Vulnerability.ID,
144-
Severity: metadata.Severity,
123+
Severity: m.Vulnerability.Metadata.Severity,
145124
Aliases: aliases,
146125
FixedVersion: getFixedVersion(m.Vulnerability),
147126
},
148127
}
149128

150-
return f, nil
129+
return f
151130
}
152131

153132
func getFixedVersion(vuln vulnerability.Vulnerability) string {

pkg/scan/finding_test.go

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
package scan
2+
3+
import (
4+
"testing"
5+
6+
"github.com/anchore/grype/grype/match"
7+
"github.com/anchore/grype/grype/pkg"
8+
"github.com/anchore/grype/grype/vulnerability"
9+
"github.com/anchore/syft/syft/file"
10+
syftPkg "github.com/anchore/syft/syft/pkg"
11+
)
12+
13+
func TestMapMatchToFinding(t *testing.T) {
14+
tests := []struct {
15+
name string
16+
match match.Match
17+
want *Finding
18+
}{
19+
{
20+
name: "basic vulnerability with metadata",
21+
match: match.Match{
22+
Vulnerability: vulnerability.Vulnerability{
23+
Reference: vulnerability.Reference{
24+
ID: "CVE-2023-1234",
25+
Namespace: "nvd:cpe",
26+
},
27+
PackageName: "test-package",
28+
Fix: vulnerability.Fix{
29+
State: vulnerability.FixStateFixed,
30+
Versions: []string{"1.0.1"},
31+
},
32+
RelatedVulnerabilities: []vulnerability.Reference{},
33+
Metadata: &vulnerability.Metadata{
34+
ID: "CVE-2023-1234",
35+
Severity: "high",
36+
},
37+
},
38+
Package: pkg.Package{
39+
ID: pkg.ID("pkg-123"),
40+
Name: "test-package",
41+
Version: "1.0.0",
42+
Type: syftPkg.ApkPkg,
43+
PURL: "pkg:apk/wolfi/[email protected]",
44+
Locations: file.NewLocationSet(
45+
file.NewLocation("/usr/bin/test"),
46+
),
47+
},
48+
},
49+
want: &Finding{
50+
Package: Package{
51+
ID: "pkg-123",
52+
Name: "test-package",
53+
Version: "1.0.0",
54+
Type: "apk",
55+
Location: "/usr/bin/test",
56+
PURL: "pkg:apk/wolfi/[email protected]",
57+
},
58+
Vulnerability: Vulnerability{
59+
ID: "CVE-2023-1234",
60+
Severity: "high",
61+
Aliases: []string{},
62+
FixedVersion: "1.0.1",
63+
},
64+
},
65+
},
66+
{
67+
name: "vulnerability with related vulnerabilities (aliases)",
68+
match: match.Match{
69+
Vulnerability: vulnerability.Vulnerability{
70+
Reference: vulnerability.Reference{
71+
ID: "CVE-2023-1234",
72+
Namespace: "nvd:cpe",
73+
},
74+
PackageName: "test-package",
75+
Fix: vulnerability.Fix{
76+
State: vulnerability.FixStateFixed,
77+
Versions: []string{"1.0.1"},
78+
},
79+
RelatedVulnerabilities: []vulnerability.Reference{
80+
{
81+
ID: "GHSA-xxxx-yyyy-zzzz",
82+
Namespace: "github:language:go",
83+
},
84+
{
85+
ID: "CVE-2023-5678",
86+
Namespace: "nvd:cpe",
87+
},
88+
},
89+
Metadata: &vulnerability.Metadata{
90+
ID: "CVE-2023-1234",
91+
Severity: "high",
92+
},
93+
},
94+
Package: pkg.Package{
95+
ID: pkg.ID("pkg-123"),
96+
Name: "test-package",
97+
Version: "1.0.0",
98+
Type: syftPkg.ApkPkg,
99+
PURL: "pkg:apk/wolfi/[email protected]",
100+
Locations: file.NewLocationSet(
101+
file.NewLocation("/usr/bin/test"),
102+
),
103+
},
104+
},
105+
want: &Finding{
106+
Package: Package{
107+
ID: "pkg-123",
108+
Name: "test-package",
109+
Version: "1.0.0",
110+
Type: "apk",
111+
Location: "/usr/bin/test",
112+
PURL: "pkg:apk/wolfi/[email protected]",
113+
},
114+
Vulnerability: Vulnerability{
115+
ID: "CVE-2023-1234",
116+
Severity: "high",
117+
Aliases: []string{"GHSA-xxxx-yyyy-zzzz", "CVE-2023-5678"},
118+
FixedVersion: "1.0.1",
119+
},
120+
},
121+
},
122+
{
123+
name: "vulnerability with self-referencing related vulnerability (should be filtered)",
124+
match: match.Match{
125+
Vulnerability: vulnerability.Vulnerability{
126+
Reference: vulnerability.Reference{
127+
ID: "CVE-2023-1234",
128+
Namespace: "nvd:cpe",
129+
},
130+
PackageName: "test-package",
131+
Fix: vulnerability.Fix{
132+
State: vulnerability.FixStateFixed,
133+
Versions: []string{"1.0.1"},
134+
},
135+
RelatedVulnerabilities: []vulnerability.Reference{
136+
{
137+
ID: "CVE-2023-1234", // Same as main vulnerability
138+
Namespace: "nvd:cpe",
139+
},
140+
{
141+
ID: "GHSA-xxxx-yyyy-zzzz",
142+
Namespace: "github:language:go",
143+
},
144+
},
145+
Metadata: &vulnerability.Metadata{
146+
ID: "CVE-2023-1234",
147+
Severity: "high",
148+
},
149+
},
150+
Package: pkg.Package{
151+
ID: pkg.ID("pkg-123"),
152+
Name: "test-package",
153+
Version: "1.0.0",
154+
Type: syftPkg.ApkPkg,
155+
PURL: "pkg:apk/wolfi/[email protected]",
156+
Locations: file.NewLocationSet(
157+
file.NewLocation("/usr/bin/test"),
158+
),
159+
},
160+
},
161+
want: &Finding{
162+
Package: Package{
163+
ID: "pkg-123",
164+
Name: "test-package",
165+
Version: "1.0.0",
166+
Type: "apk",
167+
Location: "/usr/bin/test",
168+
PURL: "pkg:apk/wolfi/[email protected]",
169+
},
170+
Vulnerability: Vulnerability{
171+
ID: "CVE-2023-1234",
172+
Severity: "high",
173+
Aliases: []string{"GHSA-xxxx-yyyy-zzzz"}, // CVE-2023-1234 filtered out
174+
FixedVersion: "1.0.1",
175+
},
176+
},
177+
},
178+
{
179+
name: "vulnerability with no fix",
180+
match: match.Match{
181+
Vulnerability: vulnerability.Vulnerability{
182+
Reference: vulnerability.Reference{
183+
ID: "CVE-2023-1234",
184+
Namespace: "nvd:cpe",
185+
},
186+
PackageName: "test-package",
187+
Fix: vulnerability.Fix{
188+
State: vulnerability.FixStateUnknown,
189+
},
190+
RelatedVulnerabilities: []vulnerability.Reference{},
191+
Metadata: &vulnerability.Metadata{
192+
ID: "CVE-2023-1234",
193+
Severity: "critical",
194+
},
195+
},
196+
Package: pkg.Package{
197+
ID: pkg.ID("pkg-123"),
198+
Name: "test-package",
199+
Version: "1.0.0",
200+
Type: syftPkg.ApkPkg,
201+
PURL: "pkg:apk/wolfi/[email protected]",
202+
Locations: file.NewLocationSet(
203+
file.NewLocation("/usr/bin/test"),
204+
),
205+
},
206+
},
207+
want: &Finding{
208+
Package: Package{
209+
ID: "pkg-123",
210+
Name: "test-package",
211+
Version: "1.0.0",
212+
Type: "apk",
213+
Location: "/usr/bin/test",
214+
PURL: "pkg:apk/wolfi/[email protected]",
215+
},
216+
Vulnerability: Vulnerability{
217+
ID: "CVE-2023-1234",
218+
Severity: "critical",
219+
Aliases: []string{},
220+
FixedVersion: "", // No fix available
221+
},
222+
},
223+
},
224+
}
225+
226+
for _, tt := range tests {
227+
t.Run(tt.name, func(t *testing.T) {
228+
got := mapMatchToFinding(tt.match)
229+
if got == nil {
230+
t.Fatal("mapMatchToFinding() returned nil")
231+
}
232+
233+
// Compare the results
234+
if got.Package.ID != tt.want.Package.ID {
235+
t.Errorf("Package.ID = %v, want %v", got.Package.ID, tt.want.Package.ID)
236+
}
237+
if got.Package.Name != tt.want.Package.Name {
238+
t.Errorf("Package.Name = %v, want %v", got.Package.Name, tt.want.Package.Name)
239+
}
240+
if got.Package.Version != tt.want.Package.Version {
241+
t.Errorf("Package.Version = %v, want %v", got.Package.Version, tt.want.Package.Version)
242+
}
243+
if got.Package.Type != tt.want.Package.Type {
244+
t.Errorf("Package.Type = %v, want %v", got.Package.Type, tt.want.Package.Type)
245+
}
246+
if got.Package.PURL != tt.want.Package.PURL {
247+
t.Errorf("Package.PURL = %v, want %v", got.Package.PURL, tt.want.Package.PURL)
248+
}
249+
250+
if got.Vulnerability.ID != tt.want.Vulnerability.ID {
251+
t.Errorf("Vulnerability.ID = %v, want %v", got.Vulnerability.ID, tt.want.Vulnerability.ID)
252+
}
253+
if got.Vulnerability.Severity != tt.want.Vulnerability.Severity {
254+
t.Errorf("Vulnerability.Severity = %v, want %v", got.Vulnerability.Severity, tt.want.Vulnerability.Severity)
255+
}
256+
if got.Vulnerability.FixedVersion != tt.want.Vulnerability.FixedVersion {
257+
t.Errorf("Vulnerability.FixedVersion = %v, want %v", got.Vulnerability.FixedVersion, tt.want.Vulnerability.FixedVersion)
258+
}
259+
260+
// Compare aliases
261+
if len(got.Vulnerability.Aliases) != len(tt.want.Vulnerability.Aliases) {
262+
t.Errorf("Vulnerability.Aliases length = %v, want %v", len(got.Vulnerability.Aliases), len(tt.want.Vulnerability.Aliases))
263+
} else {
264+
for i := range got.Vulnerability.Aliases {
265+
if got.Vulnerability.Aliases[i] != tt.want.Vulnerability.Aliases[i] {
266+
t.Errorf("Vulnerability.Aliases[%d] = %v, want %v", i, got.Vulnerability.Aliases[i], tt.want.Vulnerability.Aliases[i])
267+
}
268+
}
269+
}
270+
})
271+
}
272+
}

0 commit comments

Comments
 (0)