feat: summarize vulnerabilities in compliance reports (#3651)

This commit is contained in:
Teppei Fukuda
2023-02-28 00:09:00 +02:00
committed by GitHub
parent 719fdb1b11
commit b791362871
7 changed files with 98 additions and 8 deletions

2
go.mod
View File

@@ -8,7 +8,7 @@ require (
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/alicebob/miniredis/v2 v2.23.0 github.com/alicebob/miniredis/v2 v2.23.0
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/defsec v0.82.10-0.20230222063803-b1b6b5381ea1 github.com/aquasecurity/defsec v0.82.11-0.20230227200028-1372c6329e1f
github.com/aquasecurity/go-dep-parser v0.0.0-20230227085514-f6e7eca87043 github.com/aquasecurity/go-dep-parser v0.0.0-20230227085514-f6e7eca87043
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798

4
go.sum
View File

@@ -315,8 +315,8 @@ github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM=
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8=
github.com/aquasecurity/defsec v0.82.10-0.20230222063803-b1b6b5381ea1 h1:SXg+dQbjmays+9+ND8M5YIDgGHjugbUu9Ncq3aYjd/Y= github.com/aquasecurity/defsec v0.82.11-0.20230227200028-1372c6329e1f h1:GMsUbqXjrGzNOyxFGJt/WtJrBFXzQWtJJ2h+uoAUguQ=
github.com/aquasecurity/defsec v0.82.10-0.20230222063803-b1b6b5381ea1/go.mod h1:AJswzQrwesjdpF03Ev7lcPdr5REBJLAmDqjvOitvr94= github.com/aquasecurity/defsec v0.82.11-0.20230227200028-1372c6329e1f/go.mod h1:AJswzQrwesjdpF03Ev7lcPdr5REBJLAmDqjvOitvr94=
github.com/aquasecurity/go-dep-parser v0.0.0-20230227085514-f6e7eca87043 h1:3YbIYXC9/HLODABe2P4v3nPJjK9MEFOtOmnSbiCIXdo= github.com/aquasecurity/go-dep-parser v0.0.0-20230227085514-f6e7eca87043 h1:3YbIYXC9/HLODABe2P4v3nPJjK9MEFOtOmnSbiCIXdo=
github.com/aquasecurity/go-dep-parser v0.0.0-20230227085514-f6e7eca87043/go.mod h1:xx5OX/gVENa5dY60k9EliVvTbUf/EmRw1tJKzdskKGw= github.com/aquasecurity/go-dep-parser v0.0.0-20230227085514-f6e7eca87043/go.mod h1:xx5OX/gVENa5dY60k9EliVvTbUf/EmRw1tJKzdskKGw=
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=

View File

@@ -521,8 +521,8 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
opts.ImageConfigScanners = nil opts.ImageConfigScanners = nil
// TODO: define image-config-scanners in the spec // TODO: define image-config-scanners in the spec
if opts.Compliance.Spec.ID == "docker-cis" { if opts.Compliance.Spec.ID == "docker-cis" {
opts.Scanners = nil opts.Scanners = types.Scanners{types.VulnerabilityScanner}
opts.ImageConfigScanners = scanners opts.ImageConfigScanners = types.Scanners{types.MisconfigScanner}
} }
} }

View File

@@ -96,6 +96,8 @@ func scannerByCheckID(checkID string) types.Scanner {
return types.VulnerabilityScanner return types.VulnerabilityScanner
case strings.HasPrefix(checkID, "avd-"): case strings.HasPrefix(checkID, "avd-"):
return types.MisconfigScanner return types.MisconfigScanner
case strings.HasPrefix(checkID, "vuln-"): // custom id for filtering vulnerabilities by severity
return types.VulnerabilityScanner
default: default:
return types.UnknownScanner return types.UnknownScanner
} }

View File

@@ -0,0 +1,52 @@
package spec
import (
"github.com/samber/lo"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/types"
)
// We might be going to rewrite these functions in Rego,
// but we'll keep them for now until we need flexibility.
var customIDs = map[string]func(types.Result) types.Result{
"VULN-CRITICAL": filterCriticalVulns,
"VULN-HIGH": filterHighVulns,
}
func mapCustomIDsToFilteredResults(result types.Result, checkIDs map[types.Scanner][]string,
mapCheckByID map[string]types.Results) {
for _, ids := range checkIDs {
for _, id := range ids {
filterFunc, ok := customIDs[id]
if !ok {
continue
}
filtered := filterFunc(result)
if filtered.IsEmpty() {
continue
}
mapCheckByID[id] = types.Results{filtered}
}
}
}
func filterCriticalVulns(result types.Result) types.Result {
return filterVulns(result, dbTypes.SeverityCritical)
}
func filterHighVulns(result types.Result) types.Result {
return filterVulns(result, dbTypes.SeverityHigh)
}
func filterVulns(result types.Result, severity dbTypes.Severity) types.Result {
filtered := lo.Filter(result.Vulnerabilities, func(vuln types.DetectedVulnerability, _ int) bool {
return vuln.Severity == severity.String()
})
return types.Result{
Target: result.Target,
Class: result.Class,
Type: result.Type,
Vulnerabilities: filtered,
}
}

View File

@@ -35,6 +35,10 @@ func MapSpecCheckIDToFilteredResults(result types.Result, checkIDs map[types.Sca
Misconfigurations: []types.DetectedMisconfiguration{m}, Misconfigurations: []types.DetectedMisconfiguration{m},
}) })
} }
// Evaluate custom IDs
mapCustomIDsToFilteredResults(result, checkIDs, mapCheckByID)
return mapCheckByID return mapCheckByID
} }

View File

@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/compliance/spec" "github.com/aquasecurity/trivy/pkg/compliance/spec"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/types" "github.com/aquasecurity/trivy/pkg/types"
@@ -19,6 +20,7 @@ func TestMapSpecCheckIDToFilteredResults(t *testing.T) {
}, },
types.VulnerabilityScanner: { types.VulnerabilityScanner: {
"CVE-9999-9999", "CVE-9999-9999",
"VULN-CRITICAL",
}, },
} }
tests := []struct { tests := []struct {
@@ -96,8 +98,18 @@ func TestMapSpecCheckIDToFilteredResults(t *testing.T) {
Class: types.ClassLangPkg, Class: types.ClassLangPkg,
Type: ftypes.GoModule, Type: ftypes.GoModule,
Vulnerabilities: []types.DetectedVulnerability{ Vulnerabilities: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-9999-0001"}, {
{VulnerabilityID: "CVE-9999-9999"}, VulnerabilityID: "CVE-9999-0001",
Vulnerability: dbTypes.Vulnerability{
Severity: "CRITICAL",
},
},
{
VulnerabilityID: "CVE-9999-9999",
Vulnerability: dbTypes.Vulnerability{
Severity: "LOW",
},
},
}, },
}, },
want: map[string]types.Results{ want: map[string]types.Results{
@@ -107,7 +119,27 @@ func TestMapSpecCheckIDToFilteredResults(t *testing.T) {
Class: types.ClassLangPkg, Class: types.ClassLangPkg,
Type: ftypes.GoModule, Type: ftypes.GoModule,
Vulnerabilities: []types.DetectedVulnerability{ Vulnerabilities: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-9999-9999"}, {
VulnerabilityID: "CVE-9999-9999",
Vulnerability: dbTypes.Vulnerability{
Severity: "LOW",
},
},
},
},
},
"VULN-CRITICAL": {
{
Target: "target",
Class: types.ClassLangPkg,
Type: ftypes.GoModule,
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-9999-0001",
Vulnerability: dbTypes.Vulnerability{
Severity: "CRITICAL",
},
},
}, },
}, },
}, },