Skip to content

Commit 20925f7

Browse files
authored
Return severity in Scanner API calls (#306)
1 parent 31f8bc4 commit 20925f7

File tree

14 files changed

+383
-133
lines changed

14 files changed

+383
-133
lines changed

api/v1/models.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func VulnerabilityFromDatabaseModel(dbVuln database.Vulnerability) Vulnerability
146146
NamespaceName: dbVuln.Namespace.Name,
147147
Description: dbVuln.Description,
148148
Link: dbVuln.Link,
149-
Severity: string(dbVuln.Severity),
149+
Severity: string(databaseVulnToSeverity(dbVuln)),
150150
Metadata: dbVuln.Metadata,
151151
}
152152
if dbVuln.FixedBy != versionfmt.MaxVersion {

api/v1/nodescan/service.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func featureVersionToKernelComponent(fv database.FeatureVersion) *v1.GetNodeVuln
8989
}
9090
}
9191

92-
func (s *serviceImpl) evaluateLinuxKernelVulns(req *v1.GetNodeVulnerabilitiesRequest) ([]*v1.Vulnerability, *v1.GetNodeVulnerabilitiesResponse_KernelComponent, error) {
92+
func (s *serviceImpl) evaluateLinuxKernelVulns(req *v1.GetNodeVulnerabilitiesRequest) (string, []*v1.Vulnerability, *v1.GetNodeVulnerabilitiesResponse_KernelComponent, error) {
9393
osImage := strings.ToLower(req.GetOsImage())
9494

9595
var match *kernelparser.ParseMatch
@@ -98,14 +98,14 @@ func (s *serviceImpl) evaluateLinuxKernelVulns(req *v1.GetNodeVulnerabilitiesReq
9898
var err error
9999
match, ok, err = parser(s.db, req.GetKernelVersion(), osImage)
100100
if err != nil {
101-
return nil, nil, err
101+
return "", nil, nil, err
102102
}
103103
if !ok {
104104
continue
105105
}
106106
if match == nil {
107107
log.Debugf("%s %s matched %s, but no match found", osImage, req.GetKernelVersion(), name)
108-
return nil, nil, nil
108+
return "", nil, nil, nil
109109
}
110110
break
111111
}
@@ -114,7 +114,7 @@ func (s *serviceImpl) evaluateLinuxKernelVulns(req *v1.GetNodeVulnerabilitiesReq
114114
// Did not find relevant OS-specific kernel parser.
115115
// Defaulting to general kernel vulns from NVD.
116116
vulns, err := s.getNVDVulns("linux", "linux_kernel", req.GetKernelVersion())
117-
return vulns, &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
117+
return "", vulns, &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
118118
Name: "kernel",
119119
Version: req.GetKernelVersion(),
120120
}, err
@@ -133,7 +133,7 @@ func (s *serviceImpl) evaluateLinuxKernelVulns(req *v1.GetNodeVulnerabilitiesReq
133133

134134
databaseVulns, err := s.db.GetVulnerabilitiesForFeatureVersion(fv)
135135
if err != nil {
136-
return nil, nil, err
136+
return match.Namespace, nil, nil, err
137137
}
138138

139139
vulns := make([]*v1.Vulnerability, 0, len(databaseVulns))
@@ -159,7 +159,7 @@ func (s *serviceImpl) evaluateLinuxKernelVulns(req *v1.GetNodeVulnerabilitiesReq
159159
return vulns[i].Name < vulns[j].Name
160160
})
161161

162-
return filterInvalidVulns(vulns), featureVersionToKernelComponent(fv), nil
162+
return match.Namespace, filterInvalidVulns(vulns), featureVersionToKernelComponent(fv), nil
163163
}
164164

165165
func (s *serviceImpl) getKubernetesVuln(name, version string) ([]*v1.Vulnerability, error) {
@@ -215,7 +215,7 @@ func (s *serviceImpl) GetNodeVulnerabilities(_ context.Context, req *v1.GetNodeV
215215
var err error
216216
var resp v1.GetNodeVulnerabilitiesResponse
217217

218-
resp.KernelVulnerabilities, resp.KernelComponent, err = s.evaluateLinuxKernelVulns(req)
218+
resp.OperatingSystem, resp.KernelVulnerabilities, resp.KernelComponent, err = s.evaluateLinuxKernelVulns(req)
219219
if err != nil {
220220
return nil, status.Error(codes.Internal, err.Error())
221221
}

api/v1/severity.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package v1
2+
3+
import "github.com/stackrox/scanner/database"
4+
5+
// Severity is the uniform severity returned through the API
6+
type Severity string
7+
8+
// Severity settings for vulnerabilities
9+
const (
10+
UnknownSeverity Severity = "Unknown"
11+
LowSeverity Severity = "Low"
12+
ModerateSeverity Severity = "Moderate"
13+
ImportantSeverity Severity = "Important"
14+
CriticalSeverity Severity = "Critical"
15+
)
16+
17+
func databaseVulnToSeverity(dbVuln database.Vulnerability) Severity {
18+
switch dbVuln.Severity {
19+
case database.UnknownSeverity:
20+
return UnknownSeverity
21+
case database.NegligibleSeverity, database.LowSeverity:
22+
return LowSeverity
23+
case database.MediumSeverity:
24+
return ModerateSeverity
25+
case database.HighSeverity:
26+
return ImportantSeverity
27+
case database.CriticalSeverity, database.Defcon1Severity:
28+
return CriticalSeverity
29+
}
30+
return LowSeverity
31+
}

cmd/updater/diffdumps/cmd.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,15 @@ func sortFeatureVersionSlice(slice []database.FeatureVersion) {
187187
})
188188
}
189189

190-
func vulnsAreEqual(v1, v2 database.Vulnerability) bool {
190+
func vulnsAreEqual(v1, v2 database.Vulnerability, skipSeverityComparison bool) bool {
191191
sortFeatureVersionSlice(v1.FixedIn)
192192
sortFeatureVersionSlice(v2.FixedIn)
193+
194+
if skipSeverityComparison {
195+
// It is fine to set this to unknown w/o side effects because the vulns are passed by value and not reference
196+
v1.Severity = database.UnknownSeverity
197+
v2.Severity = database.UnknownSeverity
198+
}
193199
return reflect.DeepEqual(v1, v2)
194200
}
195201

@@ -263,7 +269,7 @@ func generateOSVulnsDiff(outputDir string, baseZipR *zip.ReadCloser, headZipR *z
263269
matchingBaseVuln, found := baseVulnsMap[key]
264270
// If the vuln was in the base, and equal to what was in the base,
265271
// skip it. Else, add.
266-
if !(found && vulnsAreEqual(matchingBaseVuln, headVuln)) {
272+
if !(found && vulnsAreEqual(matchingBaseVuln, headVuln, cfg.SkipSeverityComparison)) {
267273
filtered = append(filtered, headVuln)
268274
}
269275
}
@@ -287,6 +293,7 @@ type config struct {
287293
SkipFixableCentOSVulns bool `json:"skipFixableCentOSVulns"`
288294
IgnoreKubernetesVulns bool `json:"ignoreKubernetesVulns"`
289295
SkipUbuntuLinuxKernelVulns bool `json:"skipUbuntuLinuxKernelVulns"`
296+
SkipSeverityComparison bool `json:"skipSeverityComparison"`
290297
}
291298

292299
func Command() *cobra.Command {

cpe/cpe_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ func newDatabaseVuln(id string) database.Vulnerability {
186186
return database.Vulnerability{
187187
Name: id,
188188
Link: fmt.Sprintf("https://nvd.nist.gov/vuln/detail/%s", id),
189-
Severity: "",
189+
Severity: database.UnknownSeverity,
190190
Metadata: map[string]interface{}{
191191
"NVD": &types.Metadata{},
192192
},

e2etests/node_scan_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
230230
osImage string
231231
kernelVersion string
232232

233+
expectedOS string
233234
expectedKernelComponent *v1.GetNodeVulnerabilitiesResponse_KernelComponent
234235
expectedCVEs []expectedCVE
235236
unexpectedCVEs []string
@@ -239,6 +240,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
239240
osImage: "Ubuntu 20.04.1 LTS",
240241
kernelVersion: "5.4.0-51",
241242

243+
expectedOS: "ubuntu:20.04",
242244
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
243245
Name: "linux",
244246
Version: "5.4.0-51",
@@ -254,6 +256,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
254256
osImage: "Ubuntu 16.04.7 LTS",
255257
kernelVersion: "4.15.0-1050-gcp",
256258

259+
expectedOS: "ubuntu:16.04",
257260
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
258261
Name: "linux-gcp",
259262
Version: "4.15.0-1050",
@@ -273,6 +276,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
273276
osImage: "Ubuntu 16.04.7 LTS",
274277
kernelVersion: "4.2.0-1119-aws",
275278

279+
expectedOS: "ubuntu:16.04",
276280
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
277281
Name: "linux-aws",
278282
Version: "4.2.0-1119",
@@ -291,6 +295,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
291295
osImage: "Ubuntu 18.04.5 LTS",
292296
kernelVersion: "4.15.0-1050-aws",
293297

298+
expectedOS: "ubuntu:18.04",
294299
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
295300
Name: "linux-aws",
296301
Version: "4.15.0-1050",
@@ -311,6 +316,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
311316
osImage: "Ubuntu 18.04.5 LTS",
312317
kernelVersion: "5.3.0-1019-gke",
313318

319+
expectedOS: "ubuntu:18.04",
314320
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
315321
Name: "linux-gke-5.3",
316322
Version: "5.3.0-1019",
@@ -331,6 +337,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
331337
osImage: "Debian GNU/Linux 9 (stretch)",
332338
kernelVersion: "4.9.0-11-amd64",
333339

340+
expectedOS: "debian:9",
334341
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
335342
Name: "linux",
336343
Version: "4.9.0-11-amd64",
@@ -351,6 +358,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
351358
osImage: "OpenShift Enterprise",
352359
kernelVersion: "3.10.0-1127.el7.x86_64",
353360

361+
expectedOS: "centos:7",
354362
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
355363
Name: "kernel",
356364
Version: "3.10.0-1127.el7.x86_64",
@@ -365,6 +373,8 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
365373
{
366374
osImage: "Red Hat Enterprise Linux Server 7.8 (Maipo)",
367375
kernelVersion: "3.10.0-1127.19.1.el7.x86_64",
376+
377+
expectedOS: "centos:7",
368378
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
369379
Name: "kernel",
370380
Version: "3.10.0-1127.19.1.el7.x86_64",
@@ -379,6 +389,8 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
379389
{
380390
osImage: "CentOS Linux 7 (Core)",
381391
kernelVersion: "3.10.0-957.12.2.el7.x86_64",
392+
393+
expectedOS: "centos:7",
382394
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
383395
Name: "kernel",
384396
Version: "3.10.0-957.12.2.el7.x86_64",
@@ -393,6 +405,8 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
393405
{
394406
osImage: "Red Hat Enterprise Linux CoreOS 45.82.202008101249-0 (Ootpa)",
395407
kernelVersion: "4.18.0-193.14.3.el8_2.x86_64",
408+
409+
expectedOS: "centos:8",
396410
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
397411
Name: "kernel",
398412
Version: "4.18.0-193.14.3.el8_2.x86_64",
@@ -409,6 +423,8 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
409423
{
410424
osImage: "Amazon Linux 2",
411425
kernelVersion: "4.14.177-139.253.amzn2.x86_64",
426+
427+
expectedOS: "amzn:2",
412428
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
413429
Name: "kernel",
414430
Version: "4.14.177-139.253.amzn2.x86_64",
@@ -427,6 +443,8 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
427443
{
428444
osImage: "Docker Desktop",
429445
kernelVersion: "5.4.39-linuxkit",
446+
447+
expectedOS: "",
430448
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
431449
Name: "kernel",
432450
Version: "5.4.39-linuxkit",
@@ -443,6 +461,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
443461
osImage: "Garden Linux 184.0",
444462
kernelVersion: "5.4.0-5-cloud-amd64",
445463

464+
expectedOS: "debian:11",
446465
expectedKernelComponent: &v1.GetNodeVulnerabilitiesResponse_KernelComponent{
447466
Name: "linux",
448467
Version: "5.4.0-5-cloud-amd64",
@@ -468,6 +487,7 @@ func TestNodeKernelVulnerabilities(t *testing.T) {
468487
})
469488
require.NoError(t, err)
470489

490+
assert.Equal(t, c.expectedOS, resp.GetOperatingSystem())
471491
assert.Equal(t, c.expectedKernelComponent, resp.KernelComponent)
472492

473493
if len(resp.GetKernelVulnerabilities()) < len(c.expectedCVEs) {

0 commit comments

Comments
 (0)