From a80607b7e517d61cc13f11495dec3653efc89fc9 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Tue, 21 Nov 2023 09:59:12 +1100 Subject: [PATCH 01/25] ci: configure exhaustive linter It's either make it more sane or turn it off. --- .golangci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.golangci.yml b/.golangci.yml index cda0382b..7668f3b2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -39,6 +39,7 @@ linters: - revive - tagalign - whitespace + - musttag # deprecated linters - interfacer - golint @@ -62,5 +63,11 @@ linters-settings: audit: disabled G101: # "Look for hard-coded credentials" mode: strict + cyclop: max-complexity: 20 + + exhaustive: + # Presence of "default" case in switch statements satisfies exhaustiveness, + # even if all enum members are not listed. + default-signifies-exhaustive: true From d0f2fc142b4515c91c94c2f26deff31d5682a16d Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 20 Nov 2023 23:14:19 +1100 Subject: [PATCH 02/25] feat: add ability to parse an ignore file --- src/findingconfig/ignores.go | 88 +++++++++++++++++++++++++++++++ src/findingconfig/ignores_test.go | 79 +++++++++++++++++++++++++++ src/findingconfig/until.go | 50 ++++++++++++++++++ src/findingconfig/until_test.go | 30 +++++++++++ src/go.mod | 2 +- 5 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 src/findingconfig/ignores.go create mode 100644 src/findingconfig/ignores_test.go create mode 100644 src/findingconfig/until.go create mode 100644 src/findingconfig/until_test.go diff --git a/src/findingconfig/ignores.go b/src/findingconfig/ignores.go new file mode 100644 index 00000000..94140c59 --- /dev/null +++ b/src/findingconfig/ignores.go @@ -0,0 +1,88 @@ +package findingconfig + +import ( + "bytes" + "fmt" + "os" + + "gopkg.in/yaml.v3" +) + +// detailedIgnore represents the detailed encoding of Ignore, used +// for deserialization. Fields must match Ignore. +type detailedIgnore struct { + ID string `yaml:"id"` + Until UntilTime + Reason string +} + +// An entry in an ignore file used by the plugin. +type Ignore struct { + ID string + Until UntilTime + Reason string +} + +// UnmarshalYAML is a custom YAML unmarshaller that supports a simple string +// encoding and full encoding that specifies all fields. The simple encoding is +// the string ID, the complex version allows the full ID, Until and Reason +// triple. +func (f *Ignore) UnmarshalYAML(value *yaml.Node) error { + var deserialized Ignore + switch value.Kind { + case yaml.ScalarNode: + // simple string value, interpret as ID + deserialized.ID = value.Value + + case yaml.MappingNode: + // interpret mapping as the full version with all fields + var fields detailedIgnore + err := value.Decode(&fields) + if err != nil { + return err + } + + deserialized = Ignore(fields) + + default: + return fmt.Errorf("unknown type for ignore entry (%d) at line %d:%d", value.Kind, value.Line, value.Column) + } + + *f = deserialized + + return nil +} + +type Ignores struct { + Ignores []Ignore +} + +func LoadIgnores(filename string) ([]Ignore, error) { + content, err := os.ReadFile(filename) + if err != nil { + return nil, err + } + + var i Ignores + err = unmarshalYAML(content, &i) + if err != nil { + return nil, err + } + + return i.Ignores, nil +} + +// unmarshalYAML decodes a YAML encoded byte stream into the supplied pointer +// field, returning an error if decoding fails. Unknown keys in the source YAML +// will cause unmarshalling to fail. We use more strict parsing to help make +// configuration errors more visible to the users of the plugin. +func unmarshalYAML(in []byte, out any) error { + r := bytes.NewReader(in) + + dec := yaml.NewDecoder(r) + dec.KnownFields(true) + + err := dec.Decode(out) + + return err +} diff --git a/src/findingconfig/ignores_test.go b/src/findingconfig/ignores_test.go new file mode 100644 index 00000000..ff225ff7 --- /dev/null +++ b/src/findingconfig/ignores_test.go @@ -0,0 +1,79 @@ +package findingconfig_test + +import ( + "fmt" + "os" + "testing" + + "github.com/cultureamp/ecrscanresults/findingconfig" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLoadIgnores_Succeeds(t *testing.T) { + in := []byte(` +ignores: + - id: CVE-2023-1234 + until: 2015-02-15 + reason: We don't talk about CVE-2023-1234 + - CVE-2023-9876 +`) + f, err := os.CreateTemp(t.TempDir(), "ignores*.yaml") + require.NoError(t, err) + err = os.WriteFile(f.Name(), in, 0600) + require.NoError(t, err) + + i, err := findingconfig.LoadIgnores(f.Name()) + require.NoError(t, err) + + assert.Equal(t, []findingconfig.Ignore{ + {ID: "CVE-2023-1234", Until: findingconfig.MustParseUntil("2015-02-15"), Reason: "We don't talk about CVE-2023-1234"}, + {ID: "CVE-2023-9876", Until: findingconfig.UntilTime{}, Reason: ""}, + }, i) +} + +func TestLoadIgnores_Fails(t *testing.T) { + + cases := []struct { + in string + expectedError string + }{ + { + in: ` +ignores: + - ["nested array"] +`, + expectedError: "unknown type for ignore entry", + }, + { + in: ` +ignor: +`, + expectedError: "field ignor not found in type findingconfig.Ignores", + }, + { + in: ` +ignores: + - id: CVE-123 + until: 15-Jan-05 +`, + expectedError: "did not match the expected YYYY-MM-dd format", + }, + } + + for i, c := range cases { + t.Run(fmt.Sprintf("cases[%d]", i), func(t *testing.T) { + in := []byte(c.in) + + f, err := os.CreateTemp(t.TempDir(), "ignores*.yaml") + require.NoError(t, err) + + err = os.WriteFile(f.Name(), in, 0600) + require.NoError(t, err) + + _, err = findingconfig.LoadIgnores(f.Name()) + require.ErrorContains(t, err, c.expectedError) + }) + } + +} diff --git a/src/findingconfig/until.go b/src/findingconfig/until.go new file mode 100644 index 00000000..68165cd6 --- /dev/null +++ b/src/findingconfig/until.go @@ -0,0 +1,50 @@ +package findingconfig + +import ( + "errors" + "fmt" + "time" + + "gopkg.in/yaml.v3" +) + +const untilFormat = "2006-01-02" + +type UntilTime time.Time + +func (u *UntilTime) UnmarshalYAML(value *yaml.Node) error { + if value.Kind != yaml.ScalarNode { + return errors.New("unsupported type for Until value") + } + + t, err := ParseUntil(value.Value) + if err != nil { + return err + } + + *u = t + + return nil +} + +func (u UntilTime) String() string { + return time.Time(u).Format(untilFormat) +} + +func ParseUntil(dt string) (UntilTime, error) { + tm, err := time.Parse(untilFormat, dt) + if err != nil { + return UntilTime{}, fmt.Errorf("supplied until value '%s' did not match the expected YYYY-MM-dd format: %w", dt, err) + } + + return UntilTime(tm), nil +} + +func MustParseUntil(dt string) UntilTime { + u, err := ParseUntil(dt) + if err != nil { + panic(err) + } + + return u +} diff --git a/src/findingconfig/until_test.go b/src/findingconfig/until_test.go new file mode 100644 index 00000000..bf5fb1ae --- /dev/null +++ b/src/findingconfig/until_test.go @@ -0,0 +1,30 @@ +package findingconfig_test + +import ( + "testing" + "time" + + "github.com/cultureamp/ecrscanresults/findingconfig" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +func TestParseUntil(t *testing.T) { + type timer struct { + Until findingconfig.UntilTime + } + + in := ` +until: 2015-02-15 +` + + var out timer + err := yaml.Unmarshal([]byte(in), &out) + require.NoError(t, err) + + expected, _ := time.Parse("2006-01-02", "2015-02-15") + + assert.Equal(t, timer{findingconfig.UntilTime(expected)}, out) + +} diff --git a/src/go.mod b/src/go.mod index 792470c5..feed87cc 100644 --- a/src/go.mod +++ b/src/go.mod @@ -45,5 +45,5 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/sys v0.14.0 golang.org/x/text v0.12.0 - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v3 v3.0.1 ) From 23f4a929a7f9c0f6e7ffe29364230c8900565dbc Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:03:53 +1100 Subject: [PATCH 03/25] feat: load a series of ignore files from disk Load each then de-deplicate, allowing later definitions to override earlier ones. --- src/findingconfig/ignores.go | 49 ++++++++++++++++++ src/findingconfig/ignores_test.go | 83 +++++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 15 deletions(-) diff --git a/src/findingconfig/ignores.go b/src/findingconfig/ignores.go index 94140c59..be2ec481 100644 --- a/src/findingconfig/ignores.go +++ b/src/findingconfig/ignores.go @@ -4,6 +4,8 @@ import ( "bytes" "fmt" "os" + "slices" + "strings" "gopkg.in/yaml.v3" ) @@ -57,6 +59,49 @@ type Ignores struct { Ignores []Ignore } +// LoadExistingIgnores uses LoadIgnores to read any of the given set of files +// that exist. Repeated definitions for the same "Name" will overwrite each +// other. The later definition will take precedence. +func LoadExistingIgnores(filenames []string) ([]Ignore, error) { + ignores := []Ignore{} + + for _, name := range filenames { + if strings.HasPrefix(name, "~/") { + home, err := os.UserHomeDir() + if err != nil { + return nil, fmt.Errorf("user home directory not available: %w", err) + } + name = home + name[1:] + } + + if _, err := os.Stat(name); err != nil { + continue + } + + partial, err := LoadIgnores(name) + if err != nil { + return nil, fmt.Errorf("loading ignore file '%s' failed: %w", name, err) + } + + ignores = append(ignores, partial...) + } + + // reverse the loaded ignores so that those loaded last take precedence in the + // following operations. + slices.Reverse(ignores) + + // sort keeping duplicates in order they were loaded + slices.SortStableFunc(ignores, compareIgnoreByID) + + // remove duplicates, keeping the first one + ignores = slices.CompactFunc(ignores, func(a, b Ignore) bool { + return compareIgnoreByID(a, b) == 0 + }) + + return ignores, nil +} + +// LoadIgnores parses a YAML ignore file from the given location. func LoadIgnores(filename string) ([]Ignore, error) { content, err := os.ReadFile(filename) if err != nil { @@ -86,3 +131,7 @@ func unmarshalYAML(in []byte, out any) error { return err } + +func compareIgnoreByID(a, b Ignore) int { + return strings.Compare(a.ID, b.ID) +} diff --git a/src/findingconfig/ignores_test.go b/src/findingconfig/ignores_test.go index ff225ff7..f01caeb8 100644 --- a/src/findingconfig/ignores_test.go +++ b/src/findingconfig/ignores_test.go @@ -11,19 +11,16 @@ import ( ) func TestLoadIgnores_Succeeds(t *testing.T) { - in := []byte(` + in := ` ignores: - id: CVE-2023-1234 until: 2015-02-15 reason: We don't talk about CVE-2023-1234 - CVE-2023-9876 -`) - f, err := os.CreateTemp(t.TempDir(), "ignores*.yaml") - require.NoError(t, err) - err = os.WriteFile(f.Name(), in, 0600) - require.NoError(t, err) +` - i, err := findingconfig.LoadIgnores(f.Name()) + f := createIgnoreFile(t, in) + i, err := findingconfig.LoadIgnores(f) require.NoError(t, err) assert.Equal(t, []findingconfig.Ignore{ @@ -63,17 +60,73 @@ ignores: for i, c := range cases { t.Run(fmt.Sprintf("cases[%d]", i), func(t *testing.T) { - in := []byte(c.in) - - f, err := os.CreateTemp(t.TempDir(), "ignores*.yaml") - require.NoError(t, err) - - err = os.WriteFile(f.Name(), in, 0600) - require.NoError(t, err) + f := createIgnoreFile(t, c.in) - _, err = findingconfig.LoadIgnores(f.Name()) + _, err := findingconfig.LoadIgnores(f) require.ErrorContains(t, err, c.expectedError) }) } +} + +func TestLoadExistingIgnores(t *testing.T) { + contents := []string{ + ` +ignores: +`, + "skip", + ` +ignores: ~`, + ` +ignores: + - first-issue + - id: second-issue + reason: second issue earliest definition +`, + ` +ignores: +- id: second-issue + reason: second issue this reason should override earlier ones +- third-issue +`, + } + + files := createIgnoreFiles(t, contents) + + actual, err := findingconfig.LoadExistingIgnores(files) + require.NoError(t, err) + + assert.Equal(t, []findingconfig.Ignore{ + {ID: "first-issue", Until: findingconfig.UntilTime{}, Reason: ""}, + {ID: "second-issue", Until: findingconfig.UntilTime{}, Reason: "second issue this reason should override earlier ones"}, + {ID: "third-issue", Until: findingconfig.UntilTime{}, Reason: ""}, + }, actual) +} + +func createIgnoreFiles(t *testing.T, contents []string) []string { + t.Helper() + + files := make([]string, 0, len(contents)) + for _, c := range contents { + nm := "./file-does-not-exist.yaml" + + if c != "skip" { + nm = createIgnoreFile(t, c) + } + + files = append(files, nm) + } + + return files +} + +func createIgnoreFile(t *testing.T, contents string) string { + t.Helper() + + f, err := os.CreateTemp(t.TempDir(), "ignores*.yaml") + require.NoError(t, err) + + err = os.WriteFile(f.Name(), []byte(contents), 0600) + require.NoError(t, err) + return f.Name() } From 2f85239ba5886773cefc01db1f1b8af09147a969 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:22:04 +1100 Subject: [PATCH 04/25] feat: ignored findings affect threshold calculations Ignore configuration is read from a series of possible locations, and the downloaded findings are summarized based on the supplied configuration. --- src/finding/summary.go | 61 ++++++++++++++++++++++++ src/finding/summary_test.go | 92 +++++++++++++++++++++++++++++++++++++ src/main.go | 26 ++++++++++- src/report/annotation.go | 2 + 4 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 src/finding/summary.go create mode 100644 src/finding/summary_test.go diff --git a/src/finding/summary.go b/src/finding/summary.go new file mode 100644 index 00000000..10116f10 --- /dev/null +++ b/src/finding/summary.go @@ -0,0 +1,61 @@ +package finding + +import ( + "slices" + + "github.com/aws/aws-sdk-go-v2/service/ecr/types" + "github.com/cultureamp/ecrscanresults/findingconfig" +) + +type SeverityCount struct { + // Included is the number of findings that count towards the threshold for this severity. + Included int32 + + // Ignored is the number of findings that were ignored for the purposes of the threshold. + Ignored int32 +} + +type Summary struct { + // the counts by threshold, taking ignore configuration into account + Counts map[types.FindingSeverity]SeverityCount + + // the set of finding IDs that have been ignored by configuration + Ignored map[string]struct{} +} + +func NewSummary() Summary { + return Summary{ + Counts: map[types.FindingSeverity]SeverityCount{ + "CRITICAL": {}, + "HIGH": {}, + }, + Ignored: map[string]struct{}{}, + } +} + +func Summarize(findings *types.ImageScanFindings, ignoreConfig []findingconfig.Ignore) Summary { + + summary := NewSummary() + + for _, f := range findings.Findings { + ignored := slices.ContainsFunc(ignoreConfig, func(i findingconfig.Ignore) bool { + return i.ID == *f.Name + }) + + counts := SeverityCount{} + if c, exists := summary.Counts[f.Severity]; exists { + counts = c + } + + if ignored { + summary.Ignored[*f.Name] = struct{}{} + counts.Ignored++ + } else { + counts.Included++ + } + + summary.Counts[f.Severity] = counts + } + + return summary +} diff --git a/src/finding/summary_test.go b/src/finding/summary_test.go new file mode 100644 index 00000000..69fa9179 --- /dev/null +++ b/src/finding/summary_test.go @@ -0,0 +1,92 @@ +package finding_test + +import ( + "testing" + + "github.com/aws/aws-sdk-go-v2/service/ecr/types" + "github.com/cultureamp/ecrscanresults/finding" + "github.com/cultureamp/ecrscanresults/findingconfig" + "github.com/hexops/autogold/v2" +) + +func TestSummarize(t *testing.T) { + cases := []struct { + name string + ignores []findingconfig.Ignore + data types.ImageScanFindings + expected autogold.Value + }{ + { + name: "no vulnerabilities", + data: types.ImageScanFindings{}, + expected: autogold.Expect(finding.Summary{ + Counts: map[types.FindingSeverity]finding.SeverityCount{ + types.FindingSeverity("CRITICAL"): {}, + types.FindingSeverity("HIGH"): {}, + }, + Ignored: map[string]struct{}{}, + }), + }, + { + name: "findings with no ignores", + data: types.ImageScanFindings{ + Findings: []types.ImageScanFinding{ + f("CVE-2019-5188", "HIGH"), + f("CVE-2019-5200", "CRITICAL"), + f("CVE-2019-5189", "HIGH"), + }, + }, + expected: autogold.Expect(finding.Summary{ + Counts: map[types.FindingSeverity]finding.SeverityCount{ + types.FindingSeverity("CRITICAL"): {Included: 1}, + types.FindingSeverity("HIGH"): {Included: 2}, + }, + Ignored: map[string]struct{}{}, + }), + }, + { + name: "ignores affect counts", + data: types.ImageScanFindings{ + Findings: []types.ImageScanFinding{ + f("CVE-2019-5188", "HIGH"), + f("CVE-2019-5200", "CRITICAL"), + f("CVE-2019-5189", "HIGH"), + }, + }, + ignores: []findingconfig.Ignore{ + i("CVE-2019-5189"), // part of the summary + i("CVE-2019-6000"), // not part of it + }, + expected: autogold.Expect(finding.Summary{ + Counts: map[types.FindingSeverity]finding.SeverityCount{ + types.FindingSeverity("CRITICAL"): {Included: 1}, + types.FindingSeverity("HIGH"): { + Included: 1, + Ignored: 1, + }, + }, + Ignored: map[string]struct{}{"CVE-2019-5189": {}}, + }), + }, + } + + for _, c := range cases { + c := c + t.Run(c.name, func(t *testing.T) { + summary := finding.Summarize(&c.data, c.ignores) + + c.expected.Equal(t, summary) + }) + } +} + +func f(name string, severity types.FindingSeverity) types.ImageScanFinding { + return types.ImageScanFinding{ + Name: &name, + Severity: severity, + } +} + +func i(id string) findingconfig.Ignore { + return findingconfig.Ignore{ID: id} +} diff --git a/src/main.go b/src/main.go index 5e35d303..65cf67e8 100644 --- a/src/main.go +++ b/src/main.go @@ -12,6 +12,8 @@ import ( "github.com/aws/aws-sdk-go-v2/config" "github.com/cultureamp/ecrscanresults/buildkite" + "github.com/cultureamp/ecrscanresults/finding" + "github.com/cultureamp/ecrscanresults/findingconfig" "github.com/cultureamp/ecrscanresults/registry" "github.com/cultureamp/ecrscanresults/report" "github.com/cultureamp/ecrscanresults/runtimeerrors" @@ -106,8 +108,27 @@ func runCommand(ctx context.Context, pluginConfig Config, agent buildkite.Agent) buildkite.Logf("retrieved. %d findings in report.\n", len(findings.ImageScanFindings.Findings)) - criticalFindings := findings.ImageScanFindings.FindingSeverityCounts["CRITICAL"] - highFindings := findings.ImageScanFindings.FindingSeverityCounts["HIGH"] + buildkite.Logf("loading finding ignore files ...\n") + + ignoreConfig, err := findingconfig.LoadExistingIgnores([]string{ + ".ecr-scan-results-ignore.yaml", + ".ecr-scan-results-ignore.yml", + ".buildkite/ecr-scan-results-ignore.yaml", + ".buildkite/ecr-scan-results-ignore.yml", + "buildkite/ecr-scan-results-ignore.yaml", + "buildkite/ecr-scan-results-ignore.yml", + "~/.ecr-scan-results-ignore.yaml", + "~/.ecr-scan-results-ignore.yml", + }) + if err != nil { + return runtimeerrors.NonFatal("could not load finding ignore configuration", err) + } + + // summarize findings, taking ignore configuration into account + findingSummary := finding.Summarize(findings.ImageScanFindings, ignoreConfig) + + criticalFindings := findingSummary.Counts["CRITICAL"].Included + highFindings := findingSummary.Counts["HIGH"].Included overThreshold := criticalFindings > pluginConfig.CriticalSeverityThreshold || highFindings > pluginConfig.HighSeverityThreshold @@ -119,6 +140,7 @@ func runCommand(ctx context.Context, pluginConfig Config, agent buildkite.Agent) Image: imageID, ImageLabel: pluginConfig.ImageLabel, ScanFindings: *findings.ImageScanFindings, + FindingSummary: findingSummary, CriticalSeverityThreshold: pluginConfig.CriticalSeverityThreshold, HighSeverityThreshold: pluginConfig.HighSeverityThreshold, } diff --git a/src/report/annotation.go b/src/report/annotation.go index 5ced1f9b..c9e0c411 100644 --- a/src/report/annotation.go +++ b/src/report/annotation.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + "github.com/cultureamp/ecrscanresults/finding" "github.com/cultureamp/ecrscanresults/registry" "github.com/justincampbell/timeago" "golang.org/x/exp/maps" @@ -25,6 +26,7 @@ type AnnotationContext struct { Image registry.RegistryInfo ImageLabel string ScanFindings types.ImageScanFindings + FindingSummary finding.Summary CriticalSeverityThreshold int32 HighSeverityThreshold int32 } From 178483250483e5d8fd69a7da4c7d60698d111d1c Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:42:27 +1100 Subject: [PATCH 05/25] fix: use summarized results in report annotation --- src/report/annotation.go | 10 +++++----- src/report/annotation.gohtml | 12 ++++++------ src/report/annotation_function_test.go | 22 ++++++++++++---------- src/report/annotation_test.go | 13 ++++++++----- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/report/annotation.go b/src/report/annotation.go index c9e0c411..7b14b2a2 100644 --- a/src/report/annotation.go +++ b/src/report/annotation.go @@ -94,7 +94,7 @@ func sortFindings(findings []types.ImageScanFinding) []types.ImageScanFinding { // sort by severity rank, then CVE _descending_ slices.SortFunc(sorted, func(a, b types.ImageScanFinding) int { - sevRank := compareSeverities(string(a.Severity), string(b.Severity)) + sevRank := compareSeverities(a.Severity, b.Severity) if sevRank != 0 { return sevRank } @@ -107,7 +107,7 @@ func sortFindings(findings []types.ImageScanFinding) []types.ImageScanFinding { return sorted } -func sortSeverities(severityCounts map[string]int32) []string { +func sortSeverities(severityCounts map[types.FindingSeverity]finding.SeverityCount) []types.FindingSeverity { // severities are the map key in the incoming data structure severities := maps.Keys(severityCounts) @@ -117,15 +117,15 @@ func sortSeverities(severityCounts map[string]int32) []string { } // sort severity strings by rank, then alphabetically -func compareSeverities(a, b string) int { - rank := rankSeverity(a) - rankSeverity(b) +func compareSeverities(a, b types.FindingSeverity) int { + rank := rankSeverity(string(a)) - rankSeverity(string(b)) if rank != 0 { return rank } // for unknown severities, sort alphabetically - return strings.Compare(a, b) + return strings.Compare(string(a), string(b)) } func rankSeverity(s string) int { diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 7002a0b6..525f3c11 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -14,18 +14,18 @@ there is no indentation: indented output can be rendered differently. {{ else }}

Vulnerability summary for "{{ .Image.Name }}:{{ .Image.Tag }}"

{{ end }} -{{ if .ScanFindings.FindingSeverityCounts }} +{{ if .FindingSummary.Counts }}
-{{ $counts := .ScanFindings.FindingSeverityCounts}} +{{ $counts := .FindingSummary.Counts }} {{ range $severity := $counts | sortSeverities }} {{ $severityCount := index $counts . }} {{ $exceedsThreshold := (or - (and (eq $severity "CRITICAL") (gt $severityCount $criticalThreshold)) - (and (eq $severity "HIGH") (gt $severityCount $highThreshold)) + (and (eq $severity "CRITICAL") (gt $severityCount.Included $criticalThreshold)) + (and (eq $severity "HIGH") (gt $severityCount.Included $highThreshold)) ) }}
-
{{ $severity | lowerCase | titleCase }}
-

{{ $severityCount }}

+
{{ $severity | string | lowerCase | titleCase }}
+

{{ $severityCount.Included }}

{{ end }} diff --git a/src/report/annotation_function_test.go b/src/report/annotation_function_test.go index c5bf425d..7ad48bc3 100644 --- a/src/report/annotation_function_test.go +++ b/src/report/annotation_function_test.go @@ -3,21 +3,23 @@ package report import ( "testing" + "github.com/aws/aws-sdk-go-v2/service/ecr/types" + "github.com/cultureamp/ecrscanresults/finding" "github.com/stretchr/testify/assert" ) func TestSortSeverities(t *testing.T) { - input := map[string]int32{ - "INFORMATIONAL": 1, - "HIGH": 1, - "LOW": 1, - "MADE-UP": 1, - "AA-UNKNOWN": 1, - "UNDEFINED": 1, - "MEDIUM": 1, - "CRITICAL": 1, + input := map[types.FindingSeverity]finding.SeverityCount{ + "INFORMATIONAL": {Included: 1}, + "HIGH": {Included: 1}, + "LOW": {Included: 1}, + "MADE-UP": {Included: 1}, + "AA-UNKNOWN": {Included: 1}, + "UNDEFINED": {Included: 1}, + "MEDIUM": {Included: 1}, + "CRITICAL": {Included: 1}, } - expected := []string{ + expected := []types.FindingSeverity{ "CRITICAL", "HIGH", "MEDIUM", diff --git a/src/report/annotation_test.go b/src/report/annotation_test.go index 0874abde..2cc94a43 100644 --- a/src/report/annotation_test.go +++ b/src/report/annotation_test.go @@ -6,6 +6,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ecr/types" + "github.com/cultureamp/ecrscanresults/finding" "github.com/cultureamp/ecrscanresults/registry" "github.com/cultureamp/ecrscanresults/report" "github.com/hexops/autogold/v2" @@ -57,12 +58,14 @@ func TestReports(t *testing.T) { Tag: "digest-value", }, ImageLabel: "label of image", - ScanFindings: types.ImageScanFindings{ - FindingSeverityCounts: map[string]int32{ - "HIGH": 1, - "AA-BOGUS-SEVERITY": 1, - "CRITICAL": 1, + FindingSummary: finding.Summary{ + Counts: map[types.FindingSeverity]finding.SeverityCount{ + "HIGH": {Included: 1}, + "AA-BOGUS-SEVERITY": {Included: 1}, + "CRITICAL": {Included: 1}, }, + }, + ScanFindings: types.ImageScanFindings{ Findings: []types.ImageScanFinding{ { Name: aws.String("CVE-2019-5300"), From 7b13cc19773c4aa4d440bfb47bad2492a92a9626 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:20:38 +1100 Subject: [PATCH 06/25] fix: annotate ignored findings in report Simple version: annotates summary findings and marks findings in table when ignored. --- src/finding/summary.go | 5 + src/report/annotation.gohtml | 5 +- src/report/annotation_test.go | 101 +++++++++++++++++- .../TestReports/findings_included.golden | 7 ++ .../testdata/TestReports/image_label.golden | 1 + .../TestReports/no_vulnerabilities.golden | 1 + .../TestReports/some_findings_ignored.golden | 93 ++++++++++++++++ 7 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 src/report/testdata/TestReports/some_findings_ignored.golden diff --git a/src/finding/summary.go b/src/finding/summary.go index 10116f10..74a5deb7 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -23,6 +23,11 @@ type Summary struct { Ignored map[string]struct{} } +func (s Summary) IsIgnored(id string) bool { + _, found := s.Ignored[id] + return found +} + func NewSummary() Summary { return Summary{ Counts: map[types.FindingSeverity]SeverityCount{ diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 525f3c11..b7045b39 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -8,6 +8,7 @@ there is no indentation: indented output can be rendered differently. */}} {{ $criticalThreshold := .CriticalSeverityThreshold }} {{ $highThreshold := .HighSeverityThreshold }} +{{ $summary := .FindingSummary }} {{ if .ImageLabel }}

Vulnerability summary for "{{ .ImageLabel }}"

{{ .Image.Name }}:{{ .Image.Tag }}

@@ -26,6 +27,7 @@ there is no indentation: indented output can be rendered differently.
{{ $severity | string | lowerCase | titleCase }}

{{ $severityCount.Included }}

+{{ if $severityCount.Ignored }}+ {{ $severityCount.Ignored }} ignored{{ end }}
{{ end }} @@ -47,8 +49,9 @@ there is no indentation: indented output can be rendered differently. {{ range $f := .ScanFindings.Findings | sortFindings }} {{ $vector := $f | findingAttribute "CVSS2_VECTOR"}} +{{ $ignored := ($summary.IsIgnored $f.Name) }} -{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }} +{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }}{{ if $ignored }} (ignored){{ end }} {{ $f.Severity | string | lowerCase | titleCase }} {{ $f | findingAttribute "package_name" | nbsp }} {{ $f | findingAttribute "package_version" | nbsp }} {{ $f | findingAttribute "CVSS2_SCORE" | nbsp}} diff --git a/src/report/annotation_test.go b/src/report/annotation_test.go index 2cc94a43..f47545c8 100644 --- a/src/report/annotation_test.go +++ b/src/report/annotation_test.go @@ -145,7 +145,106 @@ func TestReports(t *testing.T) { HighSeverityThreshold: 0, }, }, - } + { + name: "some findings ignored", + data: report.AnnotationContext{ + Image: registry.RegistryInfo{ + RegistryID: "0123456789", + Region: "us-west-2", + Name: "test-repo", + Tag: "digest-value", + }, + ImageLabel: "label of image", + FindingSummary: finding.Summary{ + Counts: map[types.FindingSeverity]finding.SeverityCount{ + "HIGH": {Included: 1}, + "AA-BOGUS-SEVERITY": {Included: 0, Ignored: 1}, + "CRITICAL": {Included: 1}, + }, + Ignored: map[string]struct{}{ + "CVE-2019-5300": {}, + }, + }, + ScanFindings: types.ImageScanFindings{ + Findings: []types.ImageScanFinding{ + { + Name: aws.String("CVE-2019-5300"), + Description: aws.String("Another vulnerability."), + Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300"), + Severity: "AA-BOGUS-SEVERITY", + Attributes: []types.Attribute{ + { + Key: aws.String("package_version"), + Value: aws.String("5300-version"), + }, + { + Key: aws.String("package_name"), + Value: aws.String("5300-package"), + }, + { + Key: aws.String("CVSS2_VECTOR"), + Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), + }, + { + Key: aws.String("CVSS2_SCORE"), + Value: aws.String("10.0"), + }, + }, + }, + { + Name: aws.String("CVE-2019-5188"), + Description: aws.String("A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability."), + Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188"), + Severity: "HIGH", + Attributes: []types.Attribute{ + { + Key: aws.String("package_version"), + Value: aws.String("1.44.1-1ubuntu1.1"), + }, + { + Key: aws.String("package_name"), + Value: aws.String("e2fsprogs"), + }, + { + Key: aws.String("CVSS2_VECTOR"), + Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), + }, + { + Key: aws.String("CVSS2_SCORE"), + Value: aws.String("4.6"), + }, + }, + }, + { + Name: aws.String("CVE-2019-5200"), + Description: aws.String("Another vulnerability."), + Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200"), + Severity: "CRITICAL", + Attributes: []types.Attribute{ + { + Key: aws.String("package_version"), + Value: aws.String("5200-version"), + }, + { + Key: aws.String("package_name"), + Value: aws.String("5200-package"), + }, + { + Key: aws.String("CVSS2_VECTOR"), + Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), + }, + { + Key: aws.String("CVSS2_SCORE"), + Value: aws.String("10.0"), + }, + }, + }, + }, + }, + CriticalSeverityThreshold: 0, + HighSeverityThreshold: 0, + }, + }} for _, c := range cases { t.Run(c.name, func(t *testing.T) { diff --git a/src/report/testdata/TestReports/findings_included.golden b/src/report/testdata/TestReports/findings_included.golden index 39b50432..5a1ad1c9 100644 --- a/src/report/testdata/TestReports/findings_included.golden +++ b/src/report/testdata/TestReports/findings_included.golden @@ -2,6 +2,7 @@ +

Vulnerability summary for "label of image"

test-repo:digest-value

@@ -14,6 +15,7 @@
Critical

1

+
@@ -22,6 +24,7 @@
High

1

+
@@ -30,6 +33,7 @@
Aa-Bogus-Severity

1

+
@@ -49,6 +53,7 @@ + CVE-2019-5200 Critical @@ -58,6 +63,7 @@ + CVE-2019-5188 High @@ -67,6 +73,7 @@ + CVE-2019-5300 Aa-Bogus-Severity diff --git a/src/report/testdata/TestReports/image_label.golden b/src/report/testdata/TestReports/image_label.golden index 60183f4d..92f309cf 100644 --- a/src/report/testdata/TestReports/image_label.golden +++ b/src/report/testdata/TestReports/image_label.golden @@ -2,6 +2,7 @@ +

Vulnerability summary for "label of image"

test-repo:digest-value

diff --git a/src/report/testdata/TestReports/no_vulnerabilities.golden b/src/report/testdata/TestReports/no_vulnerabilities.golden index efdda81e..388e1d9b 100644 --- a/src/report/testdata/TestReports/no_vulnerabilities.golden +++ b/src/report/testdata/TestReports/no_vulnerabilities.golden @@ -2,6 +2,7 @@ +

Vulnerability summary for "test-repo:digest-value"

diff --git a/src/report/testdata/TestReports/some_findings_ignored.golden b/src/report/testdata/TestReports/some_findings_ignored.golden new file mode 100644 index 00000000..2a88a0a9 --- /dev/null +++ b/src/report/testdata/TestReports/some_findings_ignored.golden @@ -0,0 +1,93 @@ +` + + + + +

Vulnerability summary for "label of image"

+

test-repo:digest-value

+ + +
+ + + + +
+
Critical
+

1

+ +
+
+ + + +
+
High
+

1

+ +
+
+ + + +
+
Aa-Bogus-Severity
+

0

++ 1 ignored +
+
+ +
+ + +
+Vulnerability details +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CVESeverityEffectsCVSS scoreVector
CVE-2019-5200Critical5200-package 5200-version10.0AV:L/AC:L/Au:N/C:P/I:P/A:P
CVE-2019-5188Highe2fsprogs 1.44.1-1ubuntu1.14.6AV:L/AC:L/Au:N/C:P/I:P/A:P
CVE-2019-5300 (ignored)Aa-Bogus-Severity5300-package 5300-version10.0AV:L/AC:L/Au:N/C:P/I:P/A:P
+
+
+ +

+scan completed: | +source updated: +

+` From c26c6d54667a6a311b3faff1f5316fa0c0fe5404 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Tue, 21 Nov 2023 19:28:55 +1100 Subject: [PATCH 07/25] fix: transition to view objects for report Using the AWS structs directly was becoming cumbersome. This allows for a simpler template: adding ignore lists in the existing structure was becoming too complicated. --- src/finding/summary.go | 107 ++++++++-- src/finding/summary_test.go | 37 +++- src/main.go | 1 - src/report/annotation.go | 20 +- src/report/annotation.gohtml | 18 +- src/report/annotation_test.go | 199 +++++------------- .../TestReports/findings_included.golden | 6 - .../TestReports/some_findings_ignored.golden | 6 - 8 files changed, 192 insertions(+), 202 deletions(-) diff --git a/src/finding/summary.go b/src/finding/summary.go index 74a5deb7..9091beb0 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -2,11 +2,33 @@ package finding import ( "slices" + "time" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/cultureamp/ecrscanresults/findingconfig" ) +type Detail struct { + // The name associated with the finding, usually a CVE number. + Name string + + Uri string + + // The description of the finding. + Description string + + // The finding severity. + Severity types.FindingSeverity + + PackageName string + PackageVersion string + CVSS2Score string + CVSS2Vector string + + Ignore *findingconfig.Ignore +} + type SeverityCount struct { // Included is the number of findings that count towards the threshold for this severity. Included int32 @@ -19,13 +41,38 @@ type Summary struct { // the counts by threshold, taking ignore configuration into account Counts map[types.FindingSeverity]SeverityCount + Details []Detail + // the set of finding IDs that have been ignored by configuration - Ignored map[string]struct{} + Ignored []Detail + + // The time of the last completed image scan. + ImageScanCompletedAt *time.Time + + // The time when the vulnerability data was last scanned. + VulnerabilitySourceUpdatedAt *time.Time +} + +func (s *Summary) addDetail(d Detail) { + s.Details = append(s.Details, d) + s.updateCount(d.Severity, SeverityCount{Included: 1}) } -func (s Summary) IsIgnored(id string) bool { - _, found := s.Ignored[id] - return found +func (s *Summary) addIgnored(d Detail) { + s.Ignored = append(s.Ignored, d) + s.updateCount(d.Severity, SeverityCount{Ignored: 1}) +} + +func (s *Summary) updateCount(severity types.FindingSeverity, updateBy SeverityCount) { + counts := SeverityCount{} + if c, exists := s.Counts[severity]; exists { + counts = c + } + + counts.Ignored += updateBy.Ignored + counts.Included += updateBy.Included + + s.Counts[severity] = counts } func NewSummary() Summary { @@ -34,33 +81,59 @@ func NewSummary() Summary { "CRITICAL": {}, "HIGH": {}, }, - Ignored: map[string]struct{}{}, + Details: []Detail{}, + Ignored: []Detail{}, } } func Summarize(findings *types.ImageScanFindings, ignoreConfig []findingconfig.Ignore) Summary { - summary := NewSummary() + summary.ImageScanCompletedAt = findings.ImageScanCompletedAt + summary.VulnerabilitySourceUpdatedAt = findings.VulnerabilitySourceUpdatedAt + for _, f := range findings.Findings { - ignored := slices.ContainsFunc(ignoreConfig, func(i findingconfig.Ignore) bool { - return i.ID == *f.Name + var ignore *findingconfig.Ignore + detail := findingToDetail(f) + + index := slices.IndexFunc(ignoreConfig, func(ignore findingconfig.Ignore) bool { + return ignore.ID == detail.Name }) - counts := SeverityCount{} - if c, exists := summary.Counts[f.Severity]; exists { - counts = c + if index >= 0 { + ignore = &ignoreConfig[index] } - if ignored { - summary.Ignored[*f.Name] = struct{}{} - counts.Ignored++ + detail.Ignore = ignore + + if ignore == nil { + summary.addDetail(detail) } else { - counts.Included++ + summary.addIgnored(detail) } - - summary.Counts[f.Severity] = counts } return summary } + +func findingToDetail(finding types.ImageScanFinding) Detail { + return Detail{ + Name: aws.ToString(finding.Name), + Uri: aws.ToString(finding.Uri), + Description: aws.ToString(finding.Description), + Severity: finding.Severity, + PackageName: findingAttributeValue(finding, "package_name"), + PackageVersion: findingAttributeValue(finding, "package_version"), + CVSS2Score: findingAttributeValue(finding, "CVSS2_SCORE"), + CVSS2Vector: findingAttributeValue(finding, "CVSS2_VECTOR"), + } +} + +func findingAttributeValue(finding types.ImageScanFinding, name string) string { + for _, a := range finding.Attributes { + if aws.ToString(a.Key) == name { + return aws.ToString(a.Value) + } + } + return "" +} diff --git a/src/finding/summary_test.go b/src/finding/summary_test.go index 69fa9179..145195b4 100644 --- a/src/finding/summary_test.go +++ b/src/finding/summary_test.go @@ -24,7 +24,8 @@ func TestSummarize(t *testing.T) { types.FindingSeverity("CRITICAL"): {}, types.FindingSeverity("HIGH"): {}, }, - Ignored: map[string]struct{}{}, + Details: []finding.Detail{}, + Ignored: []finding.Detail{}, }), }, { @@ -41,7 +42,21 @@ func TestSummarize(t *testing.T) { types.FindingSeverity("CRITICAL"): {Included: 1}, types.FindingSeverity("HIGH"): {Included: 2}, }, - Ignored: map[string]struct{}{}, + Details: []finding.Detail{ + { + Name: "CVE-2019-5188", + Severity: types.FindingSeverity("HIGH"), + }, + { + Name: "CVE-2019-5200", + Severity: types.FindingSeverity("CRITICAL"), + }, + { + Name: "CVE-2019-5189", + Severity: types.FindingSeverity("HIGH"), + }, + }, + Ignored: []finding.Detail{}, }), }, { @@ -65,7 +80,23 @@ func TestSummarize(t *testing.T) { Ignored: 1, }, }, - Ignored: map[string]struct{}{"CVE-2019-5189": {}}, + Details: []finding.Detail{ + { + Name: "CVE-2019-5188", + Severity: types.FindingSeverity("HIGH"), + }, + { + Name: "CVE-2019-5200", + Severity: types.FindingSeverity("CRITICAL"), + }, + }, + Ignored: []finding.Detail{{ + Name: "CVE-2019-5189", + Severity: types.FindingSeverity("HIGH"), + Ignore: &findingconfig.Ignore{ + ID: "CVE-2019-5189", + }, + }}, }), }, } diff --git a/src/main.go b/src/main.go index 65cf67e8..0d8dcbd8 100644 --- a/src/main.go +++ b/src/main.go @@ -139,7 +139,6 @@ func runCommand(ctx context.Context, pluginConfig Config, agent buildkite.Agent) annotationCtx := report.AnnotationContext{ Image: imageID, ImageLabel: pluginConfig.ImageLabel, - ScanFindings: *findings.ImageScanFindings, FindingSummary: findingSummary, CriticalSeverityThreshold: pluginConfig.CriticalSeverityThreshold, HighSeverityThreshold: pluginConfig.HighSeverityThreshold, diff --git a/src/report/annotation.go b/src/report/annotation.go index 7b14b2a2..fd00c39a 100644 --- a/src/report/annotation.go +++ b/src/report/annotation.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/cultureamp/ecrscanresults/finding" "github.com/cultureamp/ecrscanresults/registry" @@ -25,7 +24,6 @@ var annotationTemplateSource string type AnnotationContext struct { Image registry.RegistryInfo ImageLabel string - ScanFindings types.ImageScanFindings FindingSummary finding.Summary CriticalSeverityThreshold int32 HighSeverityThreshold int32 @@ -39,8 +37,7 @@ func (c AnnotationContext) Render() ([]byte, error) { c := cases.Title(language.English) return c.String(s) }, - "lowerCase": strings.ToLower, - "findingAttribute": findingAttributeValue, + "lowerCase": strings.ToLower, "nbsp": func(input string) any { if len(input) > 0 { return input @@ -79,21 +76,12 @@ func (c AnnotationContext) Render() ([]byte, error) { return buf.Bytes(), nil } -func findingAttributeValue(name string, finding types.ImageScanFinding) string { - for _, a := range finding.Attributes { - if aws.ToString(a.Key) == name { - return aws.ToString(a.Value) - } - } - return "" -} - -func sortFindings(findings []types.ImageScanFinding) []types.ImageScanFinding { +func sortFindings(findings []finding.Detail) []finding.Detail { // shallow clone, don't affect source array sorted := slices.Clone(findings) // sort by severity rank, then CVE _descending_ - slices.SortFunc(sorted, func(a, b types.ImageScanFinding) int { + slices.SortFunc(sorted, func(a, b finding.Detail) int { sevRank := compareSeverities(a.Severity, b.Severity) if sevRank != 0 { return sevRank @@ -101,7 +89,7 @@ func sortFindings(findings []types.ImageScanFinding) []types.ImageScanFinding { // descending order of CVE, in general this means that newer CVEs will be at // the top - return strings.Compare(aws.ToString(b.Name), aws.ToString(a.Name)) + return strings.Compare(b.Name, a.Name) }) return sorted diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index b7045b39..85441e10 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -35,7 +35,7 @@ there is no indentation: indented output can be rendered differently. {{ else }}

No vulnerabilities reported.

{{ end }} -{{ if .ScanFindings.Findings }} +{{ if .FindingSummary.Details }}
Vulnerability details
@@ -47,15 +47,13 @@ there is no indentation: indented output can be rendered differently. CVSS score Vector -{{ range $f := .ScanFindings.Findings | sortFindings }} -{{ $vector := $f | findingAttribute "CVSS2_VECTOR"}} -{{ $ignored := ($summary.IsIgnored $f.Name) }} +{{ range $f := .FindingSummary.Details | sortFindings }} -{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }}{{ if $ignored }} (ignored){{ end }} +{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }}{{ if $f.Ignore }} (ignored){{ end }} {{ $f.Severity | string | lowerCase | titleCase }} -{{ $f | findingAttribute "package_name" | nbsp }} {{ $f | findingAttribute "package_version" | nbsp }} -{{ $f | findingAttribute "CVSS2_SCORE" | nbsp}} -{{ if $vector }}{{ $vector }}{{ else }} {{ end }} +{{ $f.PackageName | nbsp }} {{ $f.PackageVersion | nbsp }} +{{ $f.CVSS2Score | nbsp}} +{{ if $f.CVSS2Vector }}{{ $f.CVSS2Vector }}{{ else }} {{ end }} {{ end }} @@ -63,6 +61,6 @@ there is no indentation: indented output can be rendered differently.
{{ end }}

-scan completed: {{ .ScanFindings.ImageScanCompletedAt | timeAgo }} | -source updated: {{ .ScanFindings.VulnerabilitySourceUpdatedAt | timeAgo }} +scan completed: {{ .FindingSummary.ImageScanCompletedAt | timeAgo }} | +source updated: {{ .FindingSummary.VulnerabilitySourceUpdatedAt | timeAgo }}

diff --git a/src/report/annotation_test.go b/src/report/annotation_test.go index f47545c8..c3bf7230 100644 --- a/src/report/annotation_test.go +++ b/src/report/annotation_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/cultureamp/ecrscanresults/finding" + "github.com/cultureamp/ecrscanresults/findingconfig" "github.com/cultureamp/ecrscanresults/registry" "github.com/cultureamp/ecrscanresults/report" "github.com/hexops/autogold/v2" @@ -28,7 +28,6 @@ func TestReports(t *testing.T) { Tag: "digest-value", }, ImageLabel: "", - ScanFindings: types.ImageScanFindings{}, CriticalSeverityThreshold: 0, HighSeverityThreshold: 0, }, @@ -43,7 +42,6 @@ func TestReports(t *testing.T) { Tag: "digest-value", }, ImageLabel: "label of image", - ScanFindings: types.ImageScanFindings{}, CriticalSeverityThreshold: 0, HighSeverityThreshold: 0, }, @@ -64,80 +62,36 @@ func TestReports(t *testing.T) { "AA-BOGUS-SEVERITY": {Included: 1}, "CRITICAL": {Included: 1}, }, - }, - ScanFindings: types.ImageScanFindings{ - Findings: []types.ImageScanFinding{ + Details: []finding.Detail{ { - Name: aws.String("CVE-2019-5300"), - Description: aws.String("Another vulnerability."), - Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300"), - Severity: "AA-BOGUS-SEVERITY", - Attributes: []types.Attribute{ - { - Key: aws.String("package_version"), - Value: aws.String("5300-version"), - }, - { - Key: aws.String("package_name"), - Value: aws.String("5300-package"), - }, - { - Key: aws.String("CVSS2_VECTOR"), - Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), - }, - { - Key: aws.String("CVSS2_SCORE"), - Value: aws.String("10.0"), - }, - }, + Name: "CVE-2019-5300", + Description: "Another vulnerability.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", + Severity: "AA-BOGUS-SEVERITY", + PackageName: "5300-package", + PackageVersion: "5300-version", + CVSS2Score: "10.0", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", }, { - Name: aws.String("CVE-2019-5188"), - Description: aws.String("A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability."), - Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188"), - Severity: "HIGH", - Attributes: []types.Attribute{ - { - Key: aws.String("package_version"), - Value: aws.String("1.44.1-1ubuntu1.1"), - }, - { - Key: aws.String("package_name"), - Value: aws.String("e2fsprogs"), - }, - { - Key: aws.String("CVSS2_VECTOR"), - Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), - }, - { - Key: aws.String("CVSS2_SCORE"), - Value: aws.String("4.6"), - }, - }, + Name: "CVE-2019-5188", + Description: "A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188", + Severity: "HIGH", + PackageName: "e2fsprogs", + PackageVersion: "1.44.1-1ubuntu1.1", + CVSS2Score: "4.6", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", }, { - Name: aws.String("CVE-2019-5200"), - Description: aws.String("Another vulnerability."), - Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200"), - Severity: "CRITICAL", - Attributes: []types.Attribute{ - { - Key: aws.String("package_version"), - Value: aws.String("5200-version"), - }, - { - Key: aws.String("package_name"), - Value: aws.String("5200-package"), - }, - { - Key: aws.String("CVSS2_VECTOR"), - Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), - }, - { - Key: aws.String("CVSS2_SCORE"), - Value: aws.String("10.0"), - }, - }, + Name: "CVE-2019-5200", + Description: "Another vulnerability.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200", + Severity: "CRITICAL", + PackageName: "5200-package", + PackageVersion: "5200-version", + CVSS2Score: "10.0", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", }, }, }, @@ -161,85 +115,44 @@ func TestReports(t *testing.T) { "AA-BOGUS-SEVERITY": {Included: 0, Ignored: 1}, "CRITICAL": {Included: 1}, }, - Ignored: map[string]struct{}{ - "CVE-2019-5300": {}, - }, - }, - ScanFindings: types.ImageScanFindings{ - Findings: []types.ImageScanFinding{ + Details: []finding.Detail{ { - Name: aws.String("CVE-2019-5300"), - Description: aws.String("Another vulnerability."), - Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300"), - Severity: "AA-BOGUS-SEVERITY", - Attributes: []types.Attribute{ - { - Key: aws.String("package_version"), - Value: aws.String("5300-version"), - }, - { - Key: aws.String("package_name"), - Value: aws.String("5300-package"), - }, - { - Key: aws.String("CVSS2_VECTOR"), - Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), - }, - { - Key: aws.String("CVSS2_SCORE"), - Value: aws.String("10.0"), - }, + Name: "CVE-2019-5300", + Description: "Another vulnerability.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", + Severity: "AA-BOGUS-SEVERITY", + PackageName: "5300-package", + PackageVersion: "5300-version", + CVSS2Score: "10.0", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", + Ignore: &findingconfig.Ignore{ + ID: "CVE-2019-5300", + Until: findingconfig.MustParseUntil("2023-12-31"), + Reason: "ignored", }, }, { - Name: aws.String("CVE-2019-5188"), - Description: aws.String("A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability."), - Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188"), - Severity: "HIGH", - Attributes: []types.Attribute{ - { - Key: aws.String("package_version"), - Value: aws.String("1.44.1-1ubuntu1.1"), - }, - { - Key: aws.String("package_name"), - Value: aws.String("e2fsprogs"), - }, - { - Key: aws.String("CVSS2_VECTOR"), - Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), - }, - { - Key: aws.String("CVSS2_SCORE"), - Value: aws.String("4.6"), - }, - }, + Name: "CVE-2019-5188", + Description: "A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188", + Severity: "HIGH", + PackageName: "e2fsprogs", + PackageVersion: "1.44.1-1ubuntu1.1", + CVSS2Score: "4.6", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", }, { - Name: aws.String("CVE-2019-5200"), - Description: aws.String("Another vulnerability."), - Uri: aws.String("http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200"), - Severity: "CRITICAL", - Attributes: []types.Attribute{ - { - Key: aws.String("package_version"), - Value: aws.String("5200-version"), - }, - { - Key: aws.String("package_name"), - Value: aws.String("5200-package"), - }, - { - Key: aws.String("CVSS2_VECTOR"), - Value: aws.String("AV:L/AC:L/Au:N/C:P/I:P/A:P"), - }, - { - Key: aws.String("CVSS2_SCORE"), - Value: aws.String("10.0"), - }, - }, + Name: "CVE-2019-5200", + Description: "Another vulnerability.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200", + Severity: "CRITICAL", + PackageName: "5200-package", + PackageVersion: "5200-version", + CVSS2Score: "10.0", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", }, }, + Ignored: []finding.Detail{}, }, CriticalSeverityThreshold: 0, HighSeverityThreshold: 0, diff --git a/src/report/testdata/TestReports/findings_included.golden b/src/report/testdata/TestReports/findings_included.golden index 5a1ad1c9..f7eed569 100644 --- a/src/report/testdata/TestReports/findings_included.golden +++ b/src/report/testdata/TestReports/findings_included.golden @@ -52,8 +52,6 @@ Vector - - CVE-2019-5200 Critical @@ -62,8 +60,6 @@ AV:L/AC:L/Au:N/C:P/I:P/A:P - - CVE-2019-5188 High @@ -72,8 +68,6 @@ AV:L/AC:L/Au:N/C:P/I:P/A:P - - CVE-2019-5300 Aa-Bogus-Severity diff --git a/src/report/testdata/TestReports/some_findings_ignored.golden b/src/report/testdata/TestReports/some_findings_ignored.golden index 2a88a0a9..3447aa4f 100644 --- a/src/report/testdata/TestReports/some_findings_ignored.golden +++ b/src/report/testdata/TestReports/some_findings_ignored.golden @@ -52,8 +52,6 @@ Vector - - CVE-2019-5200 Critical @@ -62,8 +60,6 @@ AV:L/AC:L/Au:N/C:P/I:P/A:P - - CVE-2019-5188 High @@ -72,8 +68,6 @@ AV:L/AC:L/Au:N/C:P/I:P/A:P - - CVE-2019-5300 (ignored) Aa-Bogus-Severity From 9d3e184c70199f011adca973170ad962b2c93a24 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:51:30 +1100 Subject: [PATCH 08/25] feat: render ignored findings in separate table --- src/report/annotation.go | 6 +++ src/report/annotation.gohtml | 39 ++++++++++++-- src/report/annotation_test.go | 52 ++++++++++++------- .../TestReports/findings_included.golden | 7 ++- .../testdata/TestReports/image_label.golden | 2 + .../TestReports/no_vulnerabilities.golden | 2 + .../TestReports/some_findings_ignored.golden | 48 +++++++++++++++-- 7 files changed, 128 insertions(+), 28 deletions(-) diff --git a/src/report/annotation.go b/src/report/annotation.go index fd00c39a..57abea7a 100644 --- a/src/report/annotation.go +++ b/src/report/annotation.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/cultureamp/ecrscanresults/finding" + "github.com/cultureamp/ecrscanresults/findingconfig" "github.com/cultureamp/ecrscanresults/registry" "github.com/justincampbell/timeago" "golang.org/x/exp/maps" @@ -33,6 +34,7 @@ func (c AnnotationContext) Render() ([]byte, error) { t, err := template. New("annotation"). Funcs(template.FuncMap{ + "hasUntilValue": hasUntilValue, "titleCase": func(s string) string { c := cases.Title(language.English) return c.String(s) @@ -134,3 +136,7 @@ func rankSeverity(s string) int { return 100 } + +func hasUntilValue(until findingconfig.UntilTime) bool { + return time.Time(until).After(time.Time(findingconfig.UntilTime{})) +} diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 85441e10..8b6750cb 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -35,28 +35,61 @@ there is no indentation: indented output can be rendered differently. {{ else }}

No vulnerabilities reported.

{{ end }} -{{ if .FindingSummary.Details }} +{{ define "findingIgnoreUntil" }} +{{ if .Until }}{{ .Until }}{{ else }}indefinitely{{ end }} +{{ end }} +{{ define "findingIgnore"}} +{{ if .Reason }}
{{ template "findingIgnoreUntil" . }}
{{ .Reason }}
{{ else }}{{ template "findingIgnoreUntil" }}{{ end }} +{{ end }} +{{ if (or .FindingSummary.Details .FindingSummary.Ignored) }}
Vulnerability details
+{{ if .FindingSummary.Details }} - + {{ range $f := .FindingSummary.Details | sortFindings }} - + + + + + + +{{ end }} +
CVE SeverityEffectsAffects CVSS score Vector
{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }}{{ if $f.Ignore }} (ignored){{ end }}{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }}{{ if $f.Ignore }}{{ if $f.Ignore.Until }} (ignored until {{ $f.Ignore.Until }}){{ end }}{{ end }}{{ $f.Severity | string | lowerCase | titleCase }}{{ $f.PackageName | nbsp }} {{ $f.PackageVersion | nbsp }}{{ $f.CVSS2Score | nbsp}}{{ if $f.CVSS2Vector }}{{ $f.CVSS2Vector }}{{ else }} {{ end }}
+{{ end }} +{{ if .FindingSummary.Ignored }} + +
Ignored vulnerabilities
+

The below findings have been ignored for the purposes of threshold calculations. See the table for details, and adjust the plugin configuration if this is incorrect.

+ + + + + + + + +{{ range $f := .FindingSummary.Ignored | sortFindings }} + + + {{ end }}
CVESeverityIgnored until +AffectsCVSS scoreVector
{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }} {{ $f.Severity | string | lowerCase | titleCase }}{{ template "findingIgnore" $f.Ignore }} {{ $f.PackageName | nbsp }} {{ $f.PackageVersion | nbsp }} {{ $f.CVSS2Score | nbsp}} {{ if $f.CVSS2Vector }}{{ $f.CVSS2Vector }}{{ else }} {{ end }}
+{{ end }}
{{ end }} diff --git a/src/report/annotation_test.go b/src/report/annotation_test.go index c3bf7230..ce2a856a 100644 --- a/src/report/annotation_test.go +++ b/src/report/annotation_test.go @@ -111,26 +111,11 @@ func TestReports(t *testing.T) { ImageLabel: "label of image", FindingSummary: finding.Summary{ Counts: map[types.FindingSeverity]finding.SeverityCount{ - "HIGH": {Included: 1}, - "AA-BOGUS-SEVERITY": {Included: 0, Ignored: 1}, - "CRITICAL": {Included: 1}, + "HIGH": {Included: 1}, + "CRITICAL": {Included: 1, Ignored: 1}, + "LOW": {Included: 0, Ignored: 1}, }, Details: []finding.Detail{ - { - Name: "CVE-2019-5300", - Description: "Another vulnerability.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", - Severity: "AA-BOGUS-SEVERITY", - PackageName: "5300-package", - PackageVersion: "5300-version", - CVSS2Score: "10.0", - CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", - Ignore: &findingconfig.Ignore{ - ID: "CVE-2019-5300", - Until: findingconfig.MustParseUntil("2023-12-31"), - Reason: "ignored", - }, - }, { Name: "CVE-2019-5188", Description: "A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.", @@ -152,7 +137,36 @@ func TestReports(t *testing.T) { CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", }, }, - Ignored: []finding.Detail{}, + Ignored: []finding.Detail{ + { + Name: "CVE-2023-100", + Description: "A vulnerability present in some software but isn't that bad.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2023-100", + Severity: "LOW", + PackageName: "100-package", + PackageVersion: "100-version", + CVSS2Score: "4.0", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", + Ignore: &findingconfig.Ignore{ + ID: "CVE-2023-100", + }, + }, + { + Name: "CVE-2019-5300", + Description: "Another vulnerability.", + Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", + Severity: "CRITICAL", + PackageName: "5300-package", + PackageVersion: "5300-version", + CVSS2Score: "10.0", + CVSS2Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", + Ignore: &findingconfig.Ignore{ + ID: "CVE-2019-5300", + Until: findingconfig.MustParseUntil("2023-12-31"), + Reason: "Ignored to give the base image a chance to be updated", + }, + }, + }, }, CriticalSeverityThreshold: 0, HighSeverityThreshold: 0, diff --git a/src/report/testdata/TestReports/findings_included.golden b/src/report/testdata/TestReports/findings_included.golden index f7eed569..48e2f938 100644 --- a/src/report/testdata/TestReports/findings_included.golden +++ b/src/report/testdata/TestReports/findings_included.golden @@ -40,14 +40,17 @@
+ +
Vulnerability details
+ - + @@ -77,6 +80,8 @@
CVE SeverityEffectsAffects CVSS score Vector
+ +
diff --git a/src/report/testdata/TestReports/image_label.golden b/src/report/testdata/TestReports/image_label.golden index 92f309cf..187ce2d9 100644 --- a/src/report/testdata/TestReports/image_label.golden +++ b/src/report/testdata/TestReports/image_label.golden @@ -10,6 +10,8 @@

No vulnerabilities reported.

+ +

scan completed: | source updated: diff --git a/src/report/testdata/TestReports/no_vulnerabilities.golden b/src/report/testdata/TestReports/no_vulnerabilities.golden index 388e1d9b..4bd9caa5 100644 --- a/src/report/testdata/TestReports/no_vulnerabilities.golden +++ b/src/report/testdata/TestReports/no_vulnerabilities.golden @@ -9,6 +9,8 @@

No vulnerabilities reported.

+ +

scan completed: | source updated: diff --git a/src/report/testdata/TestReports/some_findings_ignored.golden b/src/report/testdata/TestReports/some_findings_ignored.golden index 3447aa4f..2851fe1b 100644 --- a/src/report/testdata/TestReports/some_findings_ignored.golden +++ b/src/report/testdata/TestReports/some_findings_ignored.golden @@ -15,7 +15,7 @@

Critical

1

- ++ 1 ignored
@@ -31,7 +31,7 @@
-
Aa-Bogus-Severity
+
Low

0

+ 1 ignored
@@ -40,14 +40,17 @@ + +
Vulnerability details
+ - + @@ -68,15 +71,50 @@ +
CVE SeverityEffectsAffects CVSS score Vector
AV:L/AC:L/Au:N/C:P/I:P/A:P
+ + + +
Ignored vulnerabilities
+

The below findings have been ignored for the purposes of threshold calculations. See the table for details, and adjust the plugin configuration if this is incorrect.

+ - - + + + + + + + + + + + + + + + + + + + +
CVE-2019-5300 (ignored)Aa-Bogus-SeverityCVESeverityIgnored until +AffectsCVSS scoreVector
CVE-2019-5300Critical +
+2023-12-31 +
Ignored to give the base image a chance to be updated
+
5300-package 5300-version 10.0 AV:L/AC:L/Au:N/C:P/I:P/A:P
CVE-2023-100Low + +indefinitely + +100-package 100-version4.0AV:L/AC:L/Au:N/C:P/I:P/A:P
+
From 088276c1733c545f2c33d9dcf75a607810e531d3 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Wed, 22 Nov 2023 13:29:22 +1100 Subject: [PATCH 09/25] fix: include finding description in annotation --- src/report/annotation.gohtml | 18 +++++++---- .../TestReports/findings_included.golden | 20 ++++++++++-- .../testdata/TestReports/image_label.golden | 2 ++ .../TestReports/no_vulnerabilities.golden | 2 ++ .../TestReports/some_findings_ignored.golden | 32 +++++++++++++++---- 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 8b6750cb..7e8acd82 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -35,11 +35,17 @@ there is no indentation: indented output can be rendered differently. {{ else }}

No vulnerabilities reported.

{{ end }} +{{ define "findingNameLink"}} +{{ if .Uri }}{{ .Name }}{{ else }}{{ .Name }}{{ end }} +{{ end }} +{{ define "findingName"}} +{{ if .Description }}
{{ template "findingNameLink" . }}
{{ .Description }}
{{ else }}{{ template "findingNameLink" . }}{{ end }} +{{ end }} {{ define "findingIgnoreUntil" }} -{{ if .Until }}{{ .Until }}{{ else }}indefinitely{{ end }} +{{ if .Until | hasUntilValue }}{{ .Until }}{{ else }}
(indefinitely)
{{ end }} {{ end }} {{ define "findingIgnore"}} -{{ if .Reason }}
{{ template "findingIgnoreUntil" . }}
{{ .Reason }}
{{ else }}{{ template "findingIgnoreUntil" }}{{ end }} +{{ if .Reason }}
{{ template "findingIgnoreUntil" . }}
{{ .Reason }}
{{ else }}{{ template "findingIgnoreUntil" . }}{{ end }} {{ end }} {{ if (or .FindingSummary.Details .FindingSummary.Ignored) }}
@@ -56,7 +62,7 @@ there is no indentation: indented output can be rendered differently. {{ range $f := .FindingSummary.Details | sortFindings }} -{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }}{{ if $f.Ignore }}{{ if $f.Ignore.Until }} (ignored until {{ $f.Ignore.Until }}){{ end }}{{ end }} +{{ template "findingName" . }} {{ $f.Severity | string | lowerCase | titleCase }} {{ $f.PackageName | nbsp }} {{ $f.PackageVersion | nbsp }} {{ $f.CVSS2Score | nbsp}} @@ -68,19 +74,19 @@ there is no indentation: indented output can be rendered differently. {{ if .FindingSummary.Ignored }}
Ignored vulnerabilities
-

The below findings have been ignored for the purposes of threshold calculations. See the table for details, and adjust the plugin configuration if this is incorrect.

+

The below findings have been ignored for the purposes of threshold calculations. See the table for details, and adjust the plugin configuration if this is incorrect.

- {{ range $f := .FindingSummary.Ignored | sortFindings }} - + diff --git a/src/report/testdata/TestReports/findings_included.golden b/src/report/testdata/TestReports/findings_included.golden index 48e2f938..8d799a60 100644 --- a/src/report/testdata/TestReports/findings_included.golden +++ b/src/report/testdata/TestReports/findings_included.golden @@ -42,6 +42,8 @@ + +
Vulnerability details
@@ -56,7 +58,11 @@
- + @@ -64,7 +70,11 @@ - + @@ -72,7 +82,11 @@ - + diff --git a/src/report/testdata/TestReports/image_label.golden b/src/report/testdata/TestReports/image_label.golden index 187ce2d9..42a08899 100644 --- a/src/report/testdata/TestReports/image_label.golden +++ b/src/report/testdata/TestReports/image_label.golden @@ -12,6 +12,8 @@ + +

scan completed: | source updated: diff --git a/src/report/testdata/TestReports/no_vulnerabilities.golden b/src/report/testdata/TestReports/no_vulnerabilities.golden index 4bd9caa5..357825e5 100644 --- a/src/report/testdata/TestReports/no_vulnerabilities.golden +++ b/src/report/testdata/TestReports/no_vulnerabilities.golden @@ -11,6 +11,8 @@ + +

scan completed: | source updated: diff --git a/src/report/testdata/TestReports/some_findings_ignored.golden b/src/report/testdata/TestReports/some_findings_ignored.golden index 2851fe1b..0b0ba825 100644 --- a/src/report/testdata/TestReports/some_findings_ignored.golden +++ b/src/report/testdata/TestReports/some_findings_ignored.golden @@ -42,6 +42,8 @@ + +

Vulnerability details
@@ -56,7 +58,11 @@
- + @@ -64,7 +70,11 @@ - + @@ -76,19 +86,23 @@
Ignored vulnerabilities
-

The below findings have been ignored for the purposes of threshold calculations. See the table for details, and adjust the plugin configuration if this is incorrect.

+

The below findings have been ignored for the purposes of threshold calculations. See the table for details, and adjust the plugin configuration if this is incorrect.

CVE SeverityIgnored until +Ignored until Affects CVSS score Vector
{{ if $f.Uri }}{{ $f.Name }}{{ else }}{{ $f.Name }}{{ end }}{{ template "findingName" . }} {{ $f.Severity | string | lowerCase | titleCase }} {{ template "findingIgnore" $f.Ignore }} {{ $f.PackageName | nbsp }} {{ $f.PackageVersion | nbsp }}
CVE-2019-5200 +
+CVE-2019-5200 +
Another vulnerability.
+
Critical 5200-package 5200-version 10.0
CVE-2019-5188 +
+CVE-2019-5188 +
A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.
+
High e2fsprogs 1.44.1-1ubuntu1.1 4.6
CVE-2019-5300 +
+CVE-2019-5300 +
Another vulnerability.
+
Aa-Bogus-Severity 5300-package 5300-version 10.0
CVE-2019-5200 +
+CVE-2019-5200 +
Another vulnerability.
+
Critical 5200-package 5200-version 10.0
CVE-2019-5188 +
+CVE-2019-5188 +
A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.
+
High e2fsprogs 1.44.1-1ubuntu1.1 4.6
- - + - + From 2d076a4cb41580d83eeea26adba0dd11f91e6e5f Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Wed, 22 Nov 2023 17:52:35 +1100 Subject: [PATCH 10/25] fix: simplify ignore parsing by only accepting map This potentially leads to more discoverability that it is possible to add `until` and `reason` fields. --- src/findingconfig/ignores.go | 40 +------------------------------ src/findingconfig/ignores_test.go | 15 ++++++++---- 2 files changed, 12 insertions(+), 43 deletions(-) diff --git a/src/findingconfig/ignores.go b/src/findingconfig/ignores.go index be2ec481..8d5eccfe 100644 --- a/src/findingconfig/ignores.go +++ b/src/findingconfig/ignores.go @@ -10,51 +10,13 @@ import ( "gopkg.in/yaml.v3" ) -// detailedIgnore represents the detailed encoding of Ignore, used -// for deserialization. Fields must match Ignore. -type detailedIgnore struct { - ID string `yaml:"id"` - Until UntilTime - Reason string -} - // An entry in an ignore file used by the plugin. type Ignore struct { - ID string + ID string `yaml:"id"` Until UntilTime Reason string } -// UnmarshalYAML is a custom YAML unmarshaller that supports a simple string -// encoding and full encoding that specifies all fields. The simple encoding is -// the string ID, the complex version allows the full ID, Until and Reason -// triple. -func (f *Ignore) UnmarshalYAML(value *yaml.Node) error { - var deserialized Ignore - switch value.Kind { - case yaml.ScalarNode: - // simple string value, interpret as ID - deserialized.ID = value.Value - - case yaml.MappingNode: - // interpret mapping as the full version with all fields - var fields detailedIgnore - err := value.Decode(&fields) - if err != nil { - return err - } - - deserialized = Ignore(fields) - - default: - return fmt.Errorf("unknown type for ignore entry (%d) at line %d:%d", value.Kind, value.Line, value.Column) - } - - *f = deserialized - - return nil -} - type Ignores struct { Ignores []Ignore } diff --git a/src/findingconfig/ignores_test.go b/src/findingconfig/ignores_test.go index f01caeb8..60840433 100644 --- a/src/findingconfig/ignores_test.go +++ b/src/findingconfig/ignores_test.go @@ -16,7 +16,7 @@ ignores: - id: CVE-2023-1234 until: 2015-02-15 reason: We don't talk about CVE-2023-1234 - - CVE-2023-9876 + - id: CVE-2023-9876 ` f := createIgnoreFile(t, in) @@ -40,7 +40,7 @@ func TestLoadIgnores_Fails(t *testing.T) { ignores: - ["nested array"] `, - expectedError: "unknown type for ignore entry", + expectedError: "cannot unmarshal !!seq", }, { in: ` @@ -56,6 +56,13 @@ ignores: `, expectedError: "did not match the expected YYYY-MM-dd format", }, + { + in: ` +ignores: + - idd: CVE-123 +`, + expectedError: "field idd not found in type", + }, } for i, c := range cases { @@ -78,7 +85,7 @@ ignores: ignores: ~`, ` ignores: - - first-issue + - id: first-issue - id: second-issue reason: second issue earliest definition `, @@ -86,7 +93,7 @@ ignores: ignores: - id: second-issue reason: second issue this reason should override earlier ones -- third-issue +- id: third-issue `, } From 8e838326eda0f0b167c914dd9b2ad01f4f8b1d7a Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Wed, 22 Nov 2023 17:55:09 +1100 Subject: [PATCH 11/25] docs: typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 10dbdde1..4b86e65a 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ for more information. Refer to how to set your [max-criticals](https://github.com/cultureamp/ecr-scan-results-buildkite-plugin#max-criticals-optional-string), and [max-highs](https://github.com/cultureamp/ecr-scan-results-buildkite-plugin#max-highs-optional-string). -### Are there guidelines on using up? +### Are there guidelines on using thresholds? Yes. Changing the `max-criticals` and `max-high` settings should not be taken lightly. From c9d25e92ea264f3145e9a1c8b55745d411d3fdd3 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Thu, 23 Nov 2023 22:12:19 +1100 Subject: [PATCH 12/25] fix: filtered expired finding config entries Remove on read so expired items don't affect cascades. --- src/findingconfig/clock.go | 15 +++++++++++++++ src/findingconfig/ignores.go | 17 +++++++++++++---- src/findingconfig/ignores_test.go | 27 ++++++++++++++++++++++----- src/main.go | 2 +- 4 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 src/findingconfig/clock.go diff --git a/src/findingconfig/clock.go b/src/findingconfig/clock.go new file mode 100644 index 00000000..d016122c --- /dev/null +++ b/src/findingconfig/clock.go @@ -0,0 +1,15 @@ +package findingconfig + +import "time" + +type SystemClock func() time.Time + +func (c SystemClock) UtcNow() time.Time { + return c() +} + +func DefaultSystemClock() SystemClock { + return SystemClock(func() time.Time { + return time.Now().UTC() + }) +} diff --git a/src/findingconfig/ignores.go b/src/findingconfig/ignores.go index 8d5eccfe..757918e0 100644 --- a/src/findingconfig/ignores.go +++ b/src/findingconfig/ignores.go @@ -6,6 +6,7 @@ import ( "os" "slices" "strings" + "time" "gopkg.in/yaml.v3" ) @@ -24,7 +25,7 @@ type Ignores struct { // LoadExistingIgnores uses LoadIgnores to read any of the given set of files // that exist. Repeated definitions for the same "Name" will overwrite each // other. The later definition will take precedence. -func LoadExistingIgnores(filenames []string) ([]Ignore, error) { +func LoadExistingIgnores(filenames []string, clock SystemClock) ([]Ignore, error) { ignores := []Ignore{} for _, name := range filenames { @@ -40,7 +41,7 @@ func LoadExistingIgnores(filenames []string) ([]Ignore, error) { continue } - partial, err := LoadIgnores(name) + partial, err := LoadIgnores(name, clock) if err != nil { return nil, fmt.Errorf("loading ignore file '%s' failed: %w", name, err) } @@ -64,7 +65,7 @@ func LoadExistingIgnores(filenames []string) ([]Ignore, error) { } // LoadIgnores parses a YAML ignore file from the given location. -func LoadIgnores(filename string) ([]Ignore, error) { +func LoadIgnores(filename string, clock SystemClock) ([]Ignore, error) { content, err := os.ReadFile(filename) if err != nil { return nil, err @@ -76,7 +77,15 @@ func LoadIgnores(filename string) ([]Ignore, error) { return nil, err } - return i.Ignores, nil + filtered := slices.DeleteFunc(i.Ignores, func(ignore Ignore) bool { + u := time.Time(ignore.Until) + z := u.IsZero() + d := !z && clock.UtcNow().After(u) + + return d + }) + + return filtered, nil } // unmarshalYAML decodes a YAML encoded byte stream into the supplied pointer diff --git a/src/findingconfig/ignores_test.go b/src/findingconfig/ignores_test.go index 60840433..4a3e76f6 100644 --- a/src/findingconfig/ignores_test.go +++ b/src/findingconfig/ignores_test.go @@ -4,27 +4,31 @@ import ( "fmt" "os" "testing" + "time" "github.com/cultureamp/ecrscanresults/findingconfig" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var defaultTime = "2023-12-01" +var defaultTestClock = testClock(defaultTime) + func TestLoadIgnores_Succeeds(t *testing.T) { in := ` ignores: - id: CVE-2023-1234 - until: 2015-02-15 + until: 2024-02-15 reason: We don't talk about CVE-2023-1234 - id: CVE-2023-9876 ` f := createIgnoreFile(t, in) - i, err := findingconfig.LoadIgnores(f) + i, err := findingconfig.LoadIgnores(f, defaultTestClock) require.NoError(t, err) assert.Equal(t, []findingconfig.Ignore{ - {ID: "CVE-2023-1234", Until: findingconfig.MustParseUntil("2015-02-15"), Reason: "We don't talk about CVE-2023-1234"}, + {ID: "CVE-2023-1234", Until: findingconfig.MustParseUntil("2024-02-15"), Reason: "We don't talk about CVE-2023-1234"}, {ID: "CVE-2023-9876", Until: findingconfig.UntilTime{}, Reason: ""}, }, i) } @@ -69,7 +73,7 @@ ignores: t.Run(fmt.Sprintf("cases[%d]", i), func(t *testing.T) { f := createIgnoreFile(t, c.in) - _, err := findingconfig.LoadIgnores(f) + _, err := findingconfig.LoadIgnores(f, defaultTestClock) require.ErrorContains(t, err, c.expectedError) }) } @@ -88,22 +92,29 @@ ignores: - id: first-issue - id: second-issue reason: second issue earliest definition + - id: fourth-issue + reason: still valid, should take precedence + until: 2023-12-31 `, ` ignores: - id: second-issue reason: second issue this reason should override earlier ones - id: third-issue +- id: fourth-issue + reason: expired should not override other 'forth-issue' + until: 2023-11-30 `, } files := createIgnoreFiles(t, contents) - actual, err := findingconfig.LoadExistingIgnores(files) + actual, err := findingconfig.LoadExistingIgnores(files, defaultTestClock) require.NoError(t, err) assert.Equal(t, []findingconfig.Ignore{ {ID: "first-issue", Until: findingconfig.UntilTime{}, Reason: ""}, + {ID: "fourth-issue", Until: findingconfig.MustParseUntil("2023-12-31"), Reason: "still valid, should take precedence"}, {ID: "second-issue", Until: findingconfig.UntilTime{}, Reason: "second issue this reason should override earlier ones"}, {ID: "third-issue", Until: findingconfig.UntilTime{}, Reason: ""}, }, actual) @@ -137,3 +148,9 @@ func createIgnoreFile(t *testing.T, contents string) string { return f.Name() } + +func testClock(yyyMMdd string) findingconfig.SystemClock { + now := time.Time(findingconfig.MustParseUntil(yyyMMdd)) + + return findingconfig.SystemClock(func() time.Time { return now }) +} diff --git a/src/main.go b/src/main.go index 0d8dcbd8..a55826ca 100644 --- a/src/main.go +++ b/src/main.go @@ -119,7 +119,7 @@ func runCommand(ctx context.Context, pluginConfig Config, agent buildkite.Agent) "buildkite/ecr-scan-results-ignore.yml", "~/.ecr-scan-results-ignore.yaml", "~/.ecr-scan-results-ignore.yml", - }) + }, findingconfig.DefaultSystemClock()) if err != nil { return runtimeerrors.NonFatal("could not load finding ignore configuration", err) } From 3f47c324767edc93a6ba34850bde49288035641c Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Wed, 22 Nov 2023 17:57:58 +1100 Subject: [PATCH 13/25] fix: correct casing of URI to align with linter --- src/finding/summary.go | 4 ++-- src/report/annotation.gohtml | 2 +- src/report/annotation_test.go | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/finding/summary.go b/src/finding/summary.go index 9091beb0..e7bc69bd 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -13,7 +13,7 @@ type Detail struct { // The name associated with the finding, usually a CVE number. Name string - Uri string + URI string // The description of the finding. Description string @@ -119,7 +119,7 @@ func Summarize(findings *types.ImageScanFindings, ignoreConfig []findingconfig.I func findingToDetail(finding types.ImageScanFinding) Detail { return Detail{ Name: aws.ToString(finding.Name), - Uri: aws.ToString(finding.Uri), + URI: aws.ToString(finding.Uri), Description: aws.ToString(finding.Description), Severity: finding.Severity, PackageName: findingAttributeValue(finding, "package_name"), diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 7e8acd82..1667cc4c 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -36,7 +36,7 @@ there is no indentation: indented output can be rendered differently.

No vulnerabilities reported.

{{ end }} {{ define "findingNameLink"}} -{{ if .Uri }}{{ .Name }}{{ else }}{{ .Name }}{{ end }} +{{ if .URI }}{{ .Name }}{{ else }}{{ .Name }}{{ end }} {{ end }} {{ define "findingName"}} {{ if .Description }}
{{ template "findingNameLink" . }}
{{ .Description }}
{{ else }}{{ template "findingNameLink" . }}{{ end }} diff --git a/src/report/annotation_test.go b/src/report/annotation_test.go index ce2a856a..0b0553fd 100644 --- a/src/report/annotation_test.go +++ b/src/report/annotation_test.go @@ -66,7 +66,7 @@ func TestReports(t *testing.T) { { Name: "CVE-2019-5300", Description: "Another vulnerability.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", + URI: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", Severity: "AA-BOGUS-SEVERITY", PackageName: "5300-package", PackageVersion: "5300-version", @@ -76,7 +76,7 @@ func TestReports(t *testing.T) { { Name: "CVE-2019-5188", Description: "A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188", + URI: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188", Severity: "HIGH", PackageName: "e2fsprogs", PackageVersion: "1.44.1-1ubuntu1.1", @@ -86,7 +86,7 @@ func TestReports(t *testing.T) { { Name: "CVE-2019-5200", Description: "Another vulnerability.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200", + URI: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200", Severity: "CRITICAL", PackageName: "5200-package", PackageVersion: "5200-version", @@ -119,7 +119,7 @@ func TestReports(t *testing.T) { { Name: "CVE-2019-5188", Description: "A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188", + URI: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5188", Severity: "HIGH", PackageName: "e2fsprogs", PackageVersion: "1.44.1-1ubuntu1.1", @@ -129,7 +129,7 @@ func TestReports(t *testing.T) { { Name: "CVE-2019-5200", Description: "Another vulnerability.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200", + URI: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5200", Severity: "CRITICAL", PackageName: "5200-package", PackageVersion: "5200-version", @@ -141,7 +141,7 @@ func TestReports(t *testing.T) { { Name: "CVE-2023-100", Description: "A vulnerability present in some software but isn't that bad.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2023-100", + URI: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2023-100", Severity: "LOW", PackageName: "100-package", PackageVersion: "100-version", @@ -154,7 +154,7 @@ func TestReports(t *testing.T) { { Name: "CVE-2019-5300", Description: "Another vulnerability.", - Uri: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", + URI: "http://people.ubuntu.com/~ubuntu-security/cve/CVE-2019-5300", Severity: "CRITICAL", PackageName: "5300-package", PackageVersion: "5300-version", From 0f087848fd29de2f874dc8dcd2dd0b465110188e Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Wed, 22 Nov 2023 23:40:34 +1100 Subject: [PATCH 14/25] fix: avoid markdown rendering in table cells An inline div surrounded by whitespace was interpreted as a Markdown paragraph when uploaded to Buildkite. --- src/report/annotation.gohtml | 16 +++------ .../TestReports/findings_included.golden | 18 ++-------- .../TestReports/some_findings_ignored.golden | 36 ++++--------------- 3 files changed, 13 insertions(+), 57 deletions(-) diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 1667cc4c..793ebbe0 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -35,18 +35,10 @@ there is no indentation: indented output can be rendered differently. {{ else }}

No vulnerabilities reported.

{{ end }} -{{ define "findingNameLink"}} -{{ if .URI }}{{ .Name }}{{ else }}{{ .Name }}{{ end }} -{{ end }} -{{ define "findingName"}} -{{ if .Description }}
{{ template "findingNameLink" . }}
{{ .Description }}
{{ else }}{{ template "findingNameLink" . }}{{ end }} -{{ end }} -{{ define "findingIgnoreUntil" }} -{{ if .Until | hasUntilValue }}{{ .Until }}{{ else }}
(indefinitely)
{{ end }} -{{ end }} -{{ define "findingIgnore"}} -{{ if .Reason }}
{{ template "findingIgnoreUntil" . }}
{{ .Reason }}
{{ else }}{{ template "findingIgnoreUntil" . }}{{ end }} -{{ end }} +{{ define "findingNameLink" }}{{ if .URI }}{{ .Name }}{{ else }}{{ .Name }}{{ end }}{{ end }} +{{ define "findingName" }}{{ if .Description }}
{{ template "findingNameLink" . }}
{{ .Description }}
{{ else }}{{ template "findingNameLink" . }}{{ end }}{{ end }} +{{ define "findingIgnoreUntil" }}{{ if .Until | hasUntilValue }}{{ .Until }}{{ else }}
(indefinitely)
{{ end }}{{ end }} +{{ define "findingIgnore"}}{{ if .Reason }}
{{ template "findingIgnoreUntil" . }}
{{ .Reason }}
{{ else }}{{ template "findingIgnoreUntil" . }}{{ end }}{{ end }} {{ if (or .FindingSummary.Details .FindingSummary.Ignored) }}
Vulnerability details diff --git a/src/report/testdata/TestReports/findings_included.golden b/src/report/testdata/TestReports/findings_included.golden index 8d799a60..b52f2e09 100644 --- a/src/report/testdata/TestReports/findings_included.golden +++ b/src/report/testdata/TestReports/findings_included.golden @@ -58,11 +58,7 @@
- + @@ -70,11 +66,7 @@ - + @@ -82,11 +74,7 @@ - + diff --git a/src/report/testdata/TestReports/some_findings_ignored.golden b/src/report/testdata/TestReports/some_findings_ignored.golden index 0b0ba825..80e5bb98 100644 --- a/src/report/testdata/TestReports/some_findings_ignored.golden +++ b/src/report/testdata/TestReports/some_findings_ignored.golden @@ -58,11 +58,7 @@ - + @@ -70,11 +66,7 @@ - + @@ -98,34 +90,18 @@ - + - + - + - + From b934c560aa8683b4887c027bc1cb613037630ca6 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Thu, 23 Nov 2023 17:48:51 +1100 Subject: [PATCH 15/25] docs: add docs for ignore file specification --- README.md | 10 +++++-- docs/ignore-findings.md | 44 +++++++++++++++++++++++++++++++ docs/img/ignore-finding-list.png | Bin 0 -> 188850 bytes docs/img/ignore-reason.png | Bin 0 -> 37684 bytes docs/img/summary-counts.png | Bin 0 -> 33907 bytes 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 docs/ignore-findings.md create mode 100644 docs/img/ignore-finding-list.png create mode 100644 docs/img/ignore-reason.png create mode 100644 docs/img/summary-counts.png diff --git a/README.md b/README.md index 4b86e65a..baa94b3d 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,12 @@ service. By default the plugin will cause the step to fail if there are critical or high vulnerabilities reported, but there are configurable thresholds on this behaviour. -> ℹ️ TIP: if you want the build to continue when vulnerabilities are found, be +> ℹ️ **TIP**: if you want the build to continue when vulnerabilities are found, be > sure to supply values for `max-criticals` and `max-highs` parameters. If these > are set to high values your build will never fail, but details will be > supplied in the annotation. > -> Check out the FAQs below for more information +> If a finding is irrelevant, or you're waiting on an upstream fix, use an "ignore" configuration file instead: see the [ignore findings](./docs/ignore-findings.md) documentation. ## Example @@ -76,12 +76,18 @@ If the number of critical vulnerabilities in the image exceeds this threshold the build is failed. Defaults to 0. Use a sufficiently large number (e.g. 999) to allow the build to always pass. +> [!IMPORTANT] +> Prefer an [ignore file](./docs/ignore-findings.md) over setting thresholds if a finding is irrelevant or time to respond is required. + ### `max-highs` (Optional, string) If the number of high vulnerabilities in the image exceeds this threshold the build is failed. Defaults to 0. Use a sufficiently large number (e.g. 999) to allow the build to always pass. +> [!IMPORTANT] +> Prefer an [ignore file](./docs/ignore-findings.md) over setting thresholds if a finding is irrelevant or time to respond is required. + ### `image-label` (Optional, string) When supplied, this is used to title the report annotation in place of the diff --git a/docs/ignore-findings.md b/docs/ignore-findings.md new file mode 100644 index 00000000..3f4b5c16 --- /dev/null +++ b/docs/ignore-findings.md @@ -0,0 +1,44 @@ +# Ignoring findings + +Findings can be ignored using a YAML file with the following structure: + +```yaml +ignores: + - id: CVE-2023-100 + - id: CVE-2023-200 + until: 2023-12-31 + reason: allowing 2 weeks for base image to update + - id: CVE-2023-300 +``` + +- each element must have at least the `id` field +- the `until` field defines the expiry of this ignore entry. This allows a team time to respond while temporarily allowing builds to continue. +- the `reason` field gives a justification that is rendered in the annotation for greater visibility. Including the "why" in this field is highly recommended. + +Ignore configuration can be specified in a number of places. If a listing for a finding with the same CVE name appears in multiple files, the most local wins: central configuration can be overridden by the repository. + +From least to most important: + +- `/etc/ecr-scan-results-buildkite-plugin/ignore.y[a]ml` (part of the agent, not modifiable by builds) +- `buildkite/ecr-scan-results-ignore.y[a]ml` (specified alongside the pipeline) +- `.buildkite/ecr-scan-results-ignore.y[a]ml` +- `.ecr-scan-results-ignore.y[a]ml` (local repository configuration) + +Configuration in the `/etc/ecr-scan-results-buildkite-plugin` directory allows for organizations to ship agents with plugin configuration that centrally manages findings that can be ignored. + +> [!IMPORTANT] +> When a finding is ignored, it is removed from consideration for threshold checks, but it's not discarded. The annotation created by the plugin adds details to the results, giving high visibility on the configured behaviour. + +## Rendering + +The summary counts at the top show the number of ignored findings: + +summary counts + +Ignored findings are separated from the main list and shown at the bottom: + +ignored finding list + +If a reason for ignoring a finding is provided, it's made available by expanding the Until date: + +ignored reason diff --git a/docs/img/ignore-finding-list.png b/docs/img/ignore-finding-list.png new file mode 100644 index 0000000000000000000000000000000000000000..b8cc9d95bbb1d6702e7ea8923ec8f52343b9473e GIT binary patch literal 188850 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%0A{={L+pQCl#tJu#=LE-B_|c}RYQ)@ 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%0AfyXb`g+|nQ@8`2M*T>>=Ti|#_xFe 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­fMiZHA zsgiOWCId38Z)W6~WJkrGGC(yk*ZTNxtZZfFXiS(7FV)FP^*?kAhy(^w|3n^$kb0o_ z94l6HK}%Iet{g|c_toVJR!KF7K$$ec%^PWtoo@pXTN}VlsT1Ydi;L=;Qfty0#pcPf zc3N7Az{d|UwR2x%aS%eV)8)GC>#^eHp9$YOjDND$1C*jrYi zyK~)m@C(G;G*Hipj@7Ok-+znW?J6=erS2)$CG{#7#45qX0V)0VqJTYi?Hdk(x781_ zB-ObTwm&~3Anv;TT8^6OuEKKuVBAA>ng|HUuY4>*Hk#Sil*gi>W-*wX@Ar!$jipn@ z0q}&f+Eh0pEAq6|{X3c=Z|SOn^Pxpb7Fk&<|2{$f_yTKpKAG$Mlz~o5_DEeZ(Ph1c zWl$wqhywW{fR^FJZ`i1vzYrH&-pcahR^Jt~y*ZSfa2Y84qG-BYnD?@d+FIZn_YuX1 zB!6Ch++6l#5s2;N6bI3R0%=)^;%W}1tFwzX_tD?K3ECEH0N}1P1oGoI;X(YjR5cdbrIST>Pp_CoC?8&(3^vlu9!|8M`xfuwSILJL)QLt$e|< z5dkNyIU*2y1ba%RlPo`_gU?@*8K`L3N%!KWr@+bTlSW;3r?p$$Rt+UZOFuJ4#%XqM zK@_QQ*QgTM&ofs~y-=vA5!vX}P;ecI(joK*Fm7!_q1Pl20i52R>G|g<^R8W$6M8{? zbCgCQ#pH-=gtjO|r0k#bHz+S&8V*Xu)poZA$Lkh^MxV!hQ-W>9Jd|j1?X`%D?SBrl z4qBtf)`8;Ebq!TD9YkWNPrkbNlGFqIOrgI`A7#+-K=j8ICzeHP@DYyupekzcx8k4n z=~T`_gejfYHAfMM+{ob$OsU=S=`CL|F<^9E_;FP*hO)joOYPSE1~RpWt?92eh|NnP z_^VAG7g*3R&4*mq@UL=+uUod@PD+c)TJC`?=*%?$Vh!ZiY>bwQO>#Quwyuo5M)-Qa z9!x`wa}@>>gZ)OPn;VxXD>n8*StMCldE3AvD6~RAtETUB+@+48G}Wk(Ax+%9R1qcqf(p=Tu&^@k`OKwW&a<{t*I9^) z?%NFf5=H8pbLMi!0r9iCYx!84@S-d|mWiU$26A*N2M<+QEBvWE&^Lp^8rPvBr#c}! zvOIhidif5&vj~1zQOLO{1s7#2J98wAnVwGruK3<%)`#V=`-^BSg2e0vKRmw`ec90E zde=$T*dlLX1gjF&fxYlpp>ql}yTp1}MI_|h+*eoqe7ONC*_?>4qXL4EB{TwQytn+zmD>pkO~im&3J%QwX|X>w=fzJ7-iOw(ghGa7CJ+Cs2WN;$dI zfJ0NlQ6&l&ezM3a0qrxvO|k78X?BY?)bRxnpHpOPl7&qV_*GQyEZU8H&Ao$1Cjuf7bLEN|h$|42o-UaQ@I9RGTVTzNkGqzU6J)ZA&w15Ir{quW{%kryf zwK76wd~kmZv~F3(p?AUGBo))bzN>Ic$07oT@m`Jx)+9%M3Lvh~sKdJ)VQtXMM(YZ* ze36tgaRl%W2ItSGWzD>RoP1d)2_o)+=sG|*cEkGR=_Xv@9kz?lCXxf&FmXCifT8<> z4;lA^0+6f;Hk6B!muqVTidyAv`sa7)LF+WJRZa0wx+z2i-mXc@S+N|D@$YIcXeT)Y zVqmh=Hah-kD-&d?lW^e0UpDz0J-k4#_QIXl$o>2HcKRj$xfr@ znDOwYDDn$w)7sb%2Eh(Q^yrSJnhYKP7#j7i|d5TTS{VnShXvSAW*fYDzhw`}10@Pl4FZ(yU!KUm4zzrRKf zcjfaW&?xo-Sd{Rpz6CUGHrvxvHN8-#fa76DP-G{Gta=2Av%|X)8x$2feZ)&>b~+k7 z@5<-uGLKNutvDV15U0%v)Krnnm~Ij?Ya7Tu5|F z?~&o`JT1*cVoZU_aL*Da0Q&UUnM;{< literal 0 HcmV?d00001 diff --git a/docs/img/ignore-reason.png b/docs/img/ignore-reason.png new file mode 100644 index 0000000000000000000000000000000000000000..6c575e39f2c31b89dac7c65f22970fd1295a7088 GIT binary patch literal 37684 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/img/summary-counts.png b/docs/img/summary-counts.png new file mode 100644 index 0000000000000000000000000000000000000000..1843b5eca4c5125d2c232c496381fdb43b2e073e GIT binary patch literal 33907 zcmeFZWm{a$)-6mo?(XjH!QCOjg1bxb#@&J?xVt4JIKiQDcS}NWcY?bI&dT2RzRrH0 zKk&XE&WGmeUev0pHEUMYoMVhyAJtVA&{0TGU|?X-l@w()U|?VuVPHU#NMPW~IAIDI z@WaGTMn+vpMutk=&Beyf(HaJZDak3Z_6^vaXt02_Z=a5bj)cS+1&k|{vpC)jhgkas zhh$PsB<%75+J@9z*h2sLtIav)2gi3Mfsuq! zl9kf(0UhNbX5tOp+!%X}5X0fU)f(4td9Ob%WZO^n4O!VNelEBEvxN>EEO?gbte-J5rV3c;ZTMxfE=p$f|L1zsd7ObfxVVzrc(t-OAfhIBO;5lwr z{ZC^!T8HHj{8T!AQ6ze26v@X4Z+@U<8#yx%;pn*1Aar5h<5900Nx{n)z<2wp#Mp7a zo5K;X|0(L`cxf&I_9a35VINccu3IkOYtb%>G6;%F`||S*XUiF}ZSIc>T~5Mp7cU>M zY5i_b$Qfr_-1h=+7Ho&ey^ZY4z6N9+D7PpNX59Ne9yhm zg|@~>cC;>C(Ky^^JA7Lx(_}pSJA7yZ+oTXj+?%u{V=( znMpP~uh7s3-|rBXa=|mGM-9ggkYrUeXT(nV9ahbKl0i%fjc==ApNEFmT2BsCl|sA6 zvv}FdtjE#`Fc1Tt1srB8Yb0M=pa^ReKM$AJr=_K-QfS0`Z4J{VSgGLagU9Z0RRu%& zys9K1G&v=T)KqX6@sj9eL6@s1pV_dk+3ktu_-+N|XAZhTyceu9az)}FSoYe5tc=`7 z=#S$fW)J2q6XMw5vg+#U7*w(o7rz;|DP}12csMI5u=G(^Kl8C|UfYO~EPo}kImqJ4cZvt`$JFm4WJJoXFb;KA9fqJU>Sy+P&F zt647yes*QzE{-D=Xrd#!XD-QoAD`=llFGT*9kUdBt1ms zETb`g?h7W^@D~I9^LL>1!^=!J9)vGe$sx#k<-80Xz5~m79nE9MAEK-QgZ2k~Helwi zA6M;8&N$$FpyslBl>8!6)&*~1Cb7o6o93u&8I%E&Y@F?};AyHzt%kJL-bR39M zBh*{T~)_dL@ zv1qI2447n(e~tHWSZyrtvDYc3oAyI%Ax6eB0)anhilB zY$c72ZWfObBBw`$m{R4ZJsu-oXO~vb!`ay;!Nt7F^SYyZ6hTxsU4yzT$4Nd5Cl_B} z<$CG3S!C@VP>R#KGT=ZxBWQq7ot+O+8ls)9K&iR1+ToI~N5wbfgAx39@tv<94%}nL zSzuy;kq|zB+zB*or4!niZQ!X2IT&t$eRJKk`P~Nab*=DniDc1n#zDwq1C9zy_8Bvn zcd#mUoiyE?qBZ*4YrCC#RZ*8B8XJ#4qGIR|Q<*i(*R1((1sPnA8|O>_*AB9KrX5bu z)dL>VLYk@o^NOTzC+_Xqz)V^qUIxAPdFS;&p;TBv6=URJp7l}h+G*6R` zZ3VVoC|tbfv+w&bB^q)jo8=mCp04?mHWpQQs7I{uu)xxVs#NNXzkTu~`J3e*7;weK zUa#ixvy-Gul<5+F%+ z|MT`b^gJ?{ATCzo&(-u>1@bhb_XW{8cp_YTo30VqRFt4ol%Sh~sK5%3tHKmUwRqMP zbZ4{}_LlP zCS?O!m4^ir5X`1rEDR#>d45kx;XA=M2ZyqK^{Fc%T!G<*0uyQO#QIuc^pr&HS9ewD zL}nMwrXD=vD6H`=+i$?#T&4sx-7FDon#r5CPCIT*sEV@aT6{42GGX@2*_5fyN^eu} z2mre{10L@*QMR_4>h zsAg}YjwuS^hd{Zk zlqDPmK@ZH)PSeDUc$R^P>B#RRfc# zqOuO<;7rmu_EZK_4DZAEnMdf(=FB97XoMD~zCMmh|K zO;Cy^F>7`EML05UX)5e~`l!k={Atcnc78M}`A6YnZ&0Qf>&u;>h~+CZTQ-Ki z%h5ntuxI2c%N*Q4QdCW! z2Mz1y^`Nc~M4c!r8%s$Z?*-X~itM(oB2oQ4y*V##p#T$VwmUc#YVk>p5hJM2inRINH{#~Re z^>Em14jj`aYMW}Z2n z1mknGzJt9&%?UB|iupdIaLeTXh_`&^VvaU>8APDb4+X1K;`KBcodi^}4`F0%L4;G`aa1 zGTBZ)l;Bmo$cbQ=SddVt&DM0>HQMR0q>xt65Ox$gDS-*Qm0q2xoe{wy-sI8qWx>mx z|1=$ZwtX)MpP7AX;*wlgwbOs}=YRmBcVi8Pc>+ams59oXlXjcrq$Wqo`E~6@$+t%8 zZ;4Q!F-5Aq-jSTk)JxmZEr_HJM9$m~L0-N6k{T`K zU=+%LsdkW3Ba8*{ zKM%mlb3BkNtQwD@zV!(mCF8Ldr>E=~c_}G@FK6l+P|bezyLl~W%ZOIZmSS17PV*wu zMlHQB+c9{WVtKok_r$@l0u#Kd_S2VQ#ffz@O!n>!NC6_-b?>)XtcpF;%(f0n=Enj0p_I;QWIv-4i zu)47*DU(3W{a2qxEzLbE3%;%xJ!x!NBq!LKQ*F@ply$OT5Fo73I4IwR^2XF=J4PPhfTjP&og_fq**;jP zBPUHYg#^(-i{c76r<>X-ho(}86vPGnd9V)Z<+PsAb^ll2qzh5tWQQtX6i1|~#E{lI zh!jx1^DO5VVh{0AQ{exc7Hy>CM5?UmMY%iaAE3^6B6>%53?Fd3^OXRf=HCYSEhU++ zZ80Pb{Q30uJz$}~z4&+c^Rd3$hFrjXiN^lF7ysIDftE@*U(9Bd`rkGD=Z1@Lz)txg zTHOD+@b4Z{`2#(yA5s?j_s{>T9gBPlH<3mDpXUD74BTmz0Mv4m$qXzV|J~{^F8K47 zFIZ#X-+lY1FjD9dHc$%%@6P`yj0N_U2K+-!vYhDeIQ*wDh&oXWsAa*jnCyRbQ4Q%s z{2sC*KJ9-Orh= zK5kxH?FxSJoYmj^6h*npylCiNd z+yio68)a!0CDzIs=?=daZ6`V;-j1avCsGdk=cjv#mnYtHa$%2mvz7XKlK*&}`Z6#G zgnM`KloCOU4R-7X4SGPx|AzvIVK0q>07wIuLHXU>x4Z(azKzk*QOg7|udDqZI-FIF zHDGO;GXR{J%;dJrvQ974;MoDM1>UXz&B)MZ0EsS%!vQL1J7gzKx7BYg;Bq3|a~#-K;r915qxvsh(?HMj0m8qKQUBlaVt!XhNc$T9_NC~* zqrXYE2~6l75C7`}&p~3_JF#%|LaH^lF?NTHnCUN{WTJ#Qg0_x_~TjC&N_SZCg=Sw?s7$2P()T@qB0L zR?+J5dlM>XK`S4th-CsGAb+%eT`tEuy6SBoR8%{g!~ffp3q64SnzOgo=5&dBg-dtI z`J59yP+m-l7l=vwG*yM@(T~dvoq%zqGzyCe=?;9p-@E#1*z6oZ0iNXouq7&zcU_;a z=S%tHfch{0mY5ePMEj^GM~D+lu*vz)zQzTQ6J9@4h<@Efx{c(wNh;j1$a)h|&ce z{3_eHgA!%RGN{Cjiv!z?@}Sb|`2|MLzYehiY?ahkVwc6L`JzIJd2e9)f6|hj4t;Nv zru5I_u^xR7kNWg_t2ZQM1`c6Xwfog5llNAg73nEjZf^?=i+NpEz;1m;R#=U-2QPJ@ zP?J{V6k*dHgvz-obGs-(`~WJ57x2AMiX-10k0H@F&EdnI07D2vX+MG*ylKbO&Qhg?3bpRx$GN< z`8)ZFKmfk00?@zE!Sl{Nq}{CqiIY+~t=N=+`GQw2tIJBOU3a!$s%)q7f&AXc|G3em zWrqOHB=CCX4G?&3loSLlzK+DeAQLn3|t&7^M@VqKbEhJ*0^YP?ONNrKiRW@XA zGH+#G$chT$MUmku>v*=_^WnJTcGaBJdK0#*4@2ZA!!!s4@_X2f;S^S3r#+k`{SJfj zv|p64yddibSCc8BANQ?c+?JChuy_x6v{MXqo(ZBro1!+fqwRqEoeWITGZ=LDvK*(T zg-}Ea=m3G?ov~s*`nTje!W!Ah8bHYfD{oH%p}i5OV_IOLG}0F%XR*_SqlGX zl`oUJ3r#kb-wjhu{V|-B2T<#xt_yKIJCSx*af!ngQ4SkCsxv&m$zx_|Z zLc&ME$VS0|!R>j}FW1Zb$uu$9|FmO{JgkUJp*$Bx?wmKpD5Le~YgYZN6b6;|D4FE! z=c!Y@>t8cWJ}a+bfmyaveTT^0WAEds5G)>+T)I|Vhse=MUe#FOf=fOB5YUX!AEGEC zn=49WJYh&YL0J2L;AuU}CR?3{QztqBZ-EtsF*$#FnV`T5aB=k?$)Z$Zbr&D|TqXzN*WNH@s& z)4*4Wh0GaX`OeZ-3Hh`=gyIC?T+Mgk3*e; z4;X20lnszC!z5a?_EABatwm~L=l!_kgutr3_2c^%)g}Pzm7v^#76NhMONo3xPocsVyxlfkkV+@fF1ryaJ>%U@j-`M*+HV9w= z^!}4)0oyD#lzbWQ!#+cwEY42-H>&klZMiB|0)4Ko0q}LLysfdy%cnUmovunS!<~o| z-G}ixiU5ZYWq98`*^{UbG6LqF#Dxc9{OS%$<*csxcd&*h0R9<2 zcX9U_Uwk7RcV0t4PVfkqvcqEcy!jj&!=nsDltGQ+uyD6!~N z0`Xs^VtE<@s`Q@R@xmiQ*Q7smiiEx%<4%D*xXrON)DZEW^$8-9GbWWjm63q^r+m21 zo47(oTAV%n)eOZHT&X@mT|K(sSNpU$f%g0+rFYZbbY+F9dn$R_knDb!~b ziRc4qN@RSWhnmD64+PYMSo(w{QC*+j;6uJ)xZK0H7{ttp<@aitHif#yChHND?iBNB zxg$pd+3+w)B_)-Tv0n9=aB9UIO0y0K*`9>ldL=+ifgaB~&74jQG1?3rn91id#Ih`; zKA&I8w9i$1*<-46;=EHrHh2EaJ0*$>Qufxnxl4}CYx6jySsX8qbOmwy2*qIeZI2nw zuY|EFZo4jXz5Q2qp>7YvfO8igL>|{AY10ktnF+V{kxo4;6+TEwoj{=@MRT&4Lti__ z05ZlfaW56B6fa`6CUS|>)Ci6=|D2_D1IqJrGdqnTa+kqOnFtD z<>4KE*3ToDiitX+Ij^d zir;tzs<&u8o_>K9?>CC|Qm-m~jRZo^0j5$eGbn~|XdqA2mpXO(f>0uB+$1*+nl!*RTIgl%hV=7?YjZyh z4lR~#R^R*YDnX13t)31K!}jPT$NN6Lj?}0X4Eus9qHaYnDotbgRe?xv2%D4pZCfU6 z=cI>vk*D2aAtVCM%ExF-72=9QV?ua02%Te_&utN*6WkI?=Kn-;*g!ht5L{@UsK>Cr zN+dy1+UM)LBqeh@8gk~Ym`2INbxS1TCfpIp5UWKvu~ceSqSLjxZ%k0#p)daLq^K1w40ieSi; zgAYie^>YM=q)oGtR0*)gS2Zn;PMsJjOrOK(e3N&Gq?Nxa^*&t<@rjk%`KI1HmTfi0=sDT$YD2~wWUfV6r-C*g~EKH|Nmqrpih zxRno7>v#tYO5IhwPO1!31R31PF@|s9mVf?2*1a!C%c-aAJ78{??`@A-!YzV`L`fc3 z+Eha~QEasajjrPijXW!}m&q`~G_C#V{uL`@f#t%0l-UV`z7mxcPa(GVxF)07a*xRr zR(K0SV3DiCSLx`!n)jBw)o8LXq9(X*n*LL^XR8eDLi}bQZ>)rn(zH5Bk>_&n*N2zD z)vaN%29a(%Bh=rGQ*6f6Y>H>dTeFx!wH%IgOX=uAp2LF5XlfZTKbH-9k!5blC%;&* zA6tQ6s0}#=f4B~1Zaf?ra|yFK3hKnb*xubG%!s_WB5Y+bw$NF+%_ae4 z@r)H4RwkEYe&*=fNG4y5wJYfI7HsMrh-v6B-~WO1HQvm(1~l91rF7(@87Pk9y?M$R z5ZAgXxyqR3@FLd_q$QrMdBzbBm(qW@S7I}*MWjWLp$!U3Mji6iblqc3H2($WO&qot z_CXeq`A=#{2w(-(jc;XAqOHNAXa*sJcyD0liTs!6Jq2fqYn4l3s;<}(aY&9Gk$Xq^ zZPT5?(L`)?74OEj<%eVAMT8v?I(6FYm?pvzP!Y*~W`)2%C4`V9p)hfhk2Me&m<-eF z2pheJNhMsl2WWM4^?u6=nfAA0^_yIy`zWsTh@}9QLc+I=R8}kF5QeJ9NyI}4JL0vw zjz(`t>?n?v;6+AjN$5f_sM@GpZocyx^0HD&Ozs_!)Tr4_12(t(c_x}`vPB3V$Umf( zhuy^*hZ_zsf0d@4s7v;v4-_V(&>sp_V?TaEkoyG*g|ntiN@l!l}t+2QkF^xj2JLkz3sQu1QI^)yD|^ zDlL%Ef6$+Q5u)w0gLrKkCAd4?x#wI4mbSgI*23&{#KDXW^Rex5qaxJ;T*4{*1%4q(D^z zRgov-1XvLbjfvP`D45WR@;{3d4Jq^E!bo(vkS7LdxM zbJWUhqQE6F#JtlNw0oTu+jy$EhCJ^R;X(=LXg5l;%&GpL1&n=^1X zloaL3@jJt&O5A}D?5lx1%?5&^U^&Cs=wC@fn@*=ooGCu_CS1`juYTO(e4zV<<*Wds z793xkQzvQ$dLPRh+4T8C*#)AuXH24`o$A}yUJjq|cV?--yB5S)+9urMTLnxWc#MbM zWP*RP*&B_-Uu2K2Rh|J&hoNT2*(JFim=SgyBUx{^^8r8xJfte$|R||JIVEhX5jV7Wvg;DsOK9xO3z(o zWqw{7@2}jqFrk!;t{+DNZZ^>neT#_|4f^!9KzTXM;%djM9U?qvAX`}FOqf;7vc-iL zNEVl&B7C=C8-qrzxc3+@rHRLUlWBPD3oOL8Xo_jc@f;qh{3 z2tslUy}S_z@Et5r{(&Q1|7J%HTZcz*KEZvw%Z6l@M)7~LtRu>DRqUdj5Db)7&-K{4 zu{S2ZV^pTZm3-#&_!HWBcQj=8{!`d)NJMo96hR%y-exqMDTmV?r9o|kC=dOp#9iwL zx2J;%gL)((0!PL|)_OO$dOYoZX2PXqOD`slB?Gs7XDxy&7s7|mt!fW~M*`L?>0TYN zyH~O>GLYrwzWKz^o1V1uxDOB0Q}LOa;k;y}gU8)p>k-U5Ks@vQaPQJD&B0YA0rJtH z&kDJh?#tK~$MVawTA}gKLBykV{rZjW96F;{i;6-c(3h(io0Nmgx48VGwM6DDG-!BG zy1h27kZu9K6&|X~g~L0s%(DSXk8Lc|QqjFY*M;9K*KNNiMb&9dI$Frd-VExa8`#== zzsfd3u8(NM60BGDEcZUlfLAtlLY1)Jpkgp_%~eTN!ZFLt?ak3HSi$ZLK^0+)4Q~lP zE@j328K@lM^BN=5275&OqhYpYg(fIvD-dmI9TE0M+o5w8 zCo;OvMyu*Ow$b%Hd!&XS|1J%=5>0FcdJv%zB-CAQuk!U#PP{77H60rq$A`2U7pB-% z!YF5(`}KV`54xHH=YHWr&zl@V43W_f){5QI40RD4B3@LLdPt9sBaUxkHA#s1u#9eC zf<2R_@SP<2ihYQi?+8}m9LZJ~{hy@YNobJ@Q*cn) zlB;sZwjUzx+;x%|3k`k=1P`T3I*l(EVvVyn;_vAmN97d|TLe%zf-9Lak_SDl#oev=2Wju?{O-(gh`c2W! zM|xcTFq8r%%@2=fEJj@G*<6V$#@P~NBITr5TUy)<1VOM=)nxcP6-o%YyY++wsAW5C zpPJr(#)_QsZL>9jpT!)vpHz9^#e(irEjp7fgfB>Mk+(Mmm)qZ)y*jk@LVExZ1u`G(tDtm-hH!HXGA80*7G->gZ*V4(?!F&CqSGLf zK?)k-N&k@r2l>p+YT>ltz}CGhF7e>pPzlktybM9+iITZX=$puI&Ur1BB0CurLKf5ji3|?;Mw}qBfjos&E=~M!a z1I5mKWtY67&TBh4u4}7L1fYU@e|5+Jd8gj}_6VRACxI{$5NcaRk$d?7oZW@?Ta!^{ zEF@n$LxzY{p%1*+Rq^8?Niilr|LzB>)O@+#!=?AXd;pO+pOK5SCjbsDVM;u40qRbm z?h?5eg5#xTQ-C@X@z_sHq^JHka}4OM9ss0LBeBLqA%9|AQK3TrMB%DwS!pFx4xIFKT?iayYK+*kfIFVX4v*dtp&Iorn^L_`= z54U<9+h4#UpzY6AQP`T!_2MwT_5l{&eve@iSMXfpH@N{xj0`BR~#zp>+1vTEXrJ& zNr&HGjrX^w)ee73_i^r-vY1t1uvCDwl1;g9^d6u^d_n-F6YpPnTa4p$F?ww7NsjU{ z!Ud}I#4SC$;B3Iup-vpFLi}IW_ny-ECX&?IXVrJF3eX#DeAy`)=)`}9CY|4@Q zAJrBUEjl%?aI_uOaZz!0T>S)8?&jyB(f?BS+hN>wpf=$0wG2qk-hU!!Ac8Ls3yIY( z4>M8OwvGq{7y?S~W!J$9aN}Q)UCjR`03e>g=h`NpO`}G#=JWke?99E|X3v8FL)OuO zk%`?a@Y?l*vr%+-+r1O$Oj;V{-2V%|3~fcHcu4-Y`pfL(wsivTEw zaoTcZwMfy~&!0E3ke05okf6WYzK}YSctW6#fyBa8)YG&^ofr`f4{|J zfQ<5mIP|ZI5I8Au+J32ed$Izsvqi52w4KIi!Cg-ms3MDO4YXqcPv=9lTMj%Ly!8w} zbd05`V!P)|gO3&JhUx%r!OU@sW+94F*kd1H!Mi&b0IAIB8x|uKAi$_VHZ!lUS44-n zDqcPVGh#dWO`Yv4i+&_t!XokvKu!+m=vxL!9IRFuDv`Ynp2kFDQpSZWoA8x7v5?Lj z2h1`|sZn&Z?Bvbv&Nh-fo?e>|Et7-ijif2=W1Sdi)jn5oXX}K zi|_?`AI+Zwn)AW+I{;5I@caE0Q|wATc{SitMI>Uv8INQd&{999sEOAqW{?-jOtRs6 z?a11AB;ORYGUfiPVK1^LKwh3tJtc9m;OO=x)Y*P@1Pob!NZR%7DB#Ti1;-Aw2U0TL zg$ErC2oW4bTX=w#~FPnw=C#)kM1UWih=eV@Jp zSTz7V8v=|jHzXQYCqRX!`@FI<@G(*?O$?CP67z@k>@4)g^EZ37c^#`KpR-vMZq*eD zb{AsY0|I@I-#_7l#o;!?X>A#DJTo^82yWaB8ttt!M7hVa<29}S5~go@Y2ngZxzs4~ zT}1mc(*fbQcv8i;R+bWGM*}z6{0W-pX2%6LU`e+938?31%b6NsR>3C0e>_zQR5H0h z?zWEj&)3z#p&!c>LE*Z{xZTu!MIngqKlMYnm`;)zg~FVbLQYNS`_Ifm=k+yy!#zJ; zs!bQUa++QAkS1nfepxnZzlKQ}9`>fkv^^=V?tF-j;*F#+8$QNjChq1pOkA4^d8Y`1z*IU9!P5mo*Q6zj=$^b(4;n119TK_um$9*@;_E}9NU2hYR zyn1q{!ur#aO}^9j!LsDXwfl`x(f3i|a(6-{6Nc|6XRw@e86sr>*DvY?!f<5PL?N)6 z=y|vb!X)OM2U)fI%kym)>|>fbv1$xp+G~Dl;tU|g@|}Uj6kQjHyq8CF!I03{Fpvt- z-6C~q4|UBp6{(hN*bP#)%Jk-Kw$Fs}3P81m8h5ApUKi@+vj7Zft|`eX(ce=*5`&lu zlgh)t_nBFLRml!bhu-tG%K1w*I1s2H^T^54_`_g+Z!qh42FPNecJ^GddPTEM$C&2i;6IY z%#OGl#8t%XvFA7ES`}Ey(fB?8n6XS6%-9=MO9k=Vz*%Gd7lpa}`;bs@T1^biUX^{xy47{AcvVXkE%-_={@8*9Fj(A=-cp~~JrZJ?=- z-REB5ZAC}Oc%7s`VXn#M*pfelP{BkAD%^D?4&wRDxxt4u&wI{ma0i^+0oJYLhwiQ^J=$a_a&2r8-N4xc4B`DkDD^J$#B@&CX5qZgRvbF+ z%QmIR=fMGNv#Fl`@4tu$8FAv;=+hiSzA_{%!w@2(Gl_UCN5Nke)+b@wIyXQc1(ud( ztGV~M{I>+JQEc~^d;FFX_He_YWk}wmBkOOuyWhLP_Ed9EnEyDxidS8KWOF4I12nVo zOPHhykc`bcS3RD|u*MW+)gAa)ljY#`WY%?pJlh9A9J2pfhT@Q<3*GVU`K4t|%K7c& z6I}#3xO>}g%bz}#s7aDD-94AGPZ8*ItATWW@agRqUUsWgh;%5=UjYo(1v(&tj zme?zogdOFq6V@8ut)KwmSss-X@$zl}JHgs=6fQEh+F9k0c)oRIC``TZnUP!Cgxy7!oS3C*uA-|(hu-8DPR)x zHLVlnlRiR)a-BMQ`NLk3%MjAs!{0z*7r2=(3)mbTHieG?nUzfnDz7(g5Fqhdz}dku zxAb|1`A5u8Bxq7^V*3vdy9P)Grrsc6O5wTgeY}*E=DPtLGX;FV2`V1H(e96&#gt=RA=NlV zTk3kj+-OF38h!Xb*L%WnJLwXSoyNwpo7=1Bcj-ItCSLTH^Ocsn&9jF^&6nUhH!9{c zB}5@c92D5kq|xrKq8Sgjr-k6c?O0=yU7Su~|x!i_by6z8Yhx)djqAlg` zYV%8iXQV>h9fQ31QCz{tlLy@HcW~teB!u#oqpPfboB^k1H;6yDmEww|-m-!slc(Q) zvo|?*EQi*dI*U4Y90#N4WUvnQI4>mB3O=yEXoWa&JTAv%2&=*B#O4ZwoSS;iX!FIw zU`l!g3DPNqkiUeeQUAhy73*$SN&GIqF%H(9fa4(~STB9DH*~pVNBs(-0PJN4kuWKU zxJVoVYXR;t4I3DxZdf&8P0!-Cp{r7}`NDW+*u$IQzlU0U3s9!vHFe>=*wuY=J$@?H zfCu4?KT6pBiQj`PJuFnOV`QBGg?B; zcD_icCp|NiM^JU!#U8AO9Kyb&>F0gMxp96MEhQK#|k ztS1ejC$6x4el+FVMAMP}`g)WQEPDO)8OQ=CUvSX%yX%J48o4}{C8mbHE~I6z{tCx0 zHHW+Vl~FX-zRS&GR@)zFdos8I7g}UFEBeZcz{YSnI05H$itKh%Hmy6(QJ;%o?{d-W zql@Om`g+kCatK9iX92<5eD#-nQE^=a%7Wm_t6jFrV`o>|Epm8z z)YQeBX-Flgoo=C~j`qMyE0>kjhQ!&)5$P$SRW9A8`{e?bQ)OIa;x1qJQy-mK%=?bU z1pEx(d}Su(R`0@U(*}-PjQR6j0U}Ce(8{Xd0ZcG$gk4Hu$PiJUW>-sSq9LI@ea5~| zRd@c|ugmE-?|4^ao+Flv_g(Y8fwN4nKlfRC zy&E7^VlTkg53uUymsg4?f}2D(W8LXuq=ZNh5$X+R0vM3 zwK<94OIv$r6R`y3+{X+FY5r@9$CqWAK8#o2a~Jw1`cVjxM17xH$hp9>yt+`EFD+KV zADoJQl8`~G8C7$KEr)IukG0kZUuryitW%1%l(|q8imaw+_DNoQv$m(gb`#ai?VYF_due>)#V1YS7S}0!?Du+ z0Z_iH_@u7RZK+7<&%hDB7Cyp~Pc7EtEQCQ5%Hn6q^*$2aN*G>=v>Df(nY|-O-2)S? z98@32dc(IoK;|#Mq_&-v8AheM5+(0jD?Q=V-vZgu>dBZzCfU{D9HzVd9E-_b=dn~_ z*)FRv7G^L9d7Y==er&m3X9`k2koEKhvs#N z(jSg^i4^v09Gd7pJ-Vg0jR**LR#Zg^6eA zlY*T1dN~ih@aRSF>vnt?#CsuK`|hqMdK8<$Sr@kGl)q;$E0!7y|F9(W{yA;=9JNj! z#+P)Rr|_wX6D_WlbX~F}a6em=4pP!YmQa{%i1)Pf;k|Nb6 zMAA?1vFts8-JGKvwSFyOjqlAe7~k9)be}No=znl@XUst{srP)xANo$M*NDtKSeduQ zsoqK3bK41}MOq#AuAqwwXG?qOmzz>csCu6KEX3r;ISGPj%mLTkjoO1La58m1H~d=p zj<8;U{%hNGioRA#=({i9Ugai`u2M{dGGh0Vt@VRr_mCtgHjhjnCnxpnzUx13Vm6fk zhzJCVGJuB>+U;uId2?XMwCXu$98qCFKSu-(IK#9#GFk0BBwagw4do8-n09u8;+;;` z#8Tqcs7j@+PrKeVxD>C!P5^5Z<#J}fg2-t|x3jof>?Uy#3>&KiDfxqKk;-S9;bWeU}ZARDGLPH-|p1%8%! z&cwfJN%pcpM-&H%As!pZ;ue#U5pZSEZByO9QKCW-pi)KhNQ>iI_pWTvu!9mm@dgb=HVk(+Y1^+r-vBHAf%2@Buv8=XCSD^#1`fN)MZ3Q*Q zxXP7~7yDv*NA<_S@1?mA%58_r3SSStGss|Lk`sz6>w+y0Y^Ig}5<(r}L-I7d4t&ax zpDf)nLSUkp_VTW>GnF3xZ%jpz`~&XZh1}CieE3U1mmB{mG(PIvz40)orSpwceYO2+ zXzgQ>WG6|SG^!;6MJI?n#FYHt379|Q7I(2s_OQPg1DJlb3nWJ4to&9LoV1S3^-s7J z$PJm}4_JvcseA>G5(o1o>VDTj*%$G#dP7=3a%T<=48VXg>tVqGN&+qR&Q9Xqr&d0H z>YaK^>V@3piBfojlObIq+;>srIP?e#Hc)KYii1P-JS&D5UyDpiZ3@2tixdW_kh8h% zQ*;{*ExS=JjSm0Y_#=_%5ddaH5nTx31Leccmw-f+KkRi4-~wmd#g1?+(D&Tq9oT=0 z&yR$v&b|!=U3l}ey~#s`;7UQIW*W(MC;VF!5-8exzo%|xb*nZChXTo3jc{PUW1m9u z!ThIQe4O@zN17AQtUf2hJb9a(4055%AN?vT%`T>*2X*PNlH!S*{;Q(E8ylEJ1+eOz zwAn{v;^%1Yv~?$N$aqy=oQ6o_=`F2PJ59AG=%M&y{PfzSb9B)0@f>c!vAnDC%_AZOD>*x@Mswzm?C${7}hR z?I5QSA>J_BggXqik(s@vRb}$xr+b&a%$Q1&3P<{aYw5nXU-fpuiI3wED#_Z8b;itV zIQ5(!b#@f<7xixHU-b1tvt>hE2qGmeBkghh@#`7NM{Y{LNmH%o*tt3ODTm@7NQXIl zJAWavXHVa>fsETt0t$IL4Vyb$`f^tC4tSkKGkk!Rrw96rS$ZldQo7g?e*e6Cj?6L1H)vPmLt^nY?`gu^ zUjf1I@No@&_>5?PDFv}13psht@p+S{cYglY;9`F;P21~_Jziw^Q0@NY3^8US;k(FB z`vzRJmy{ghs8?Oww%qIQr63e-ZNeMfFD7bLCiE+Jy zY#D^GVb%+mt8~e-gMcZD;`7DqY5j5G%pn%l9Sx(;L!8=qqS)k}SeuvY8^5mepv>4H zc5&IzFX1AnBUdj^&I}E+{mWSO#H2QgdN>wT;Yy!QgXYqZJ8lr+9ngbG;N%N#wanOX zNYbC_bkgR{2Ri~n!C?fuRUHDx31|?GKKJq9&kxD#gT|4s^Oq(P0k$~}hcfY1D4DZi zS1IK3Nvq5Bx#q##;UoN$R`Do+_D0SY_%Fa2g*=kHfY^Qq`t}L|=pG(!CSaoN25eEcZ@!-3`-GkUfG*)n;vYb z^^vy;T~KiY*Qg;SXQC^v&zGC9?+xq!Y45Dxs@%GFj|fOecS|E6-K_{nhtl0hFKH=J zIwho}RFDP%=~$AB29=PGMW?XnJaf6<{eAcT1J3#3oa5!i59@;U%qQl2#u)cKK691( zI!TJ_b6PvYw<6IX32HW*TKOmW15#XsWnOc9_5s`4!HJJv4R5^=eP2LOO7)S#3dJlruqN) z-fQ9V!nvDq1U1Y^Cc6Aq?$j(ZORwT@S$dQR$jLQm&Bdgs&*f1RZ(WLVB0xzx zmR^Pqze%)AMOr^;yu8rl??Y^&fM54Ce>?h^K@)+wP>m`>ap}l{zHumkyQeHd#2hQWkY{;XZ**fk%t4OvPW#V;lFwX zHMN0Ao;vDQQvLT>{v2@w*@kEW|1kb91wWYt43kA@X0!BP$7@73OHcR|3jOOVSVDoW z|9{DlIev`M)UXC&a-~Vyw4LtTsJ$O`oUSdk=(r>;P26Nf1sWny_1a{T$kZaecKSe< z{`*I`G zFjFKL$P~ zX5?&8p~I=7ooi2+CKEJtK|ers?X*%iKYRm^?=uTL^6N`3)Q6l!tw@MWK`s=gosBBw z-DQNPf6w4c8}iyH*EaAc*iDYO^$(`9bM`;h=NDt*4ZJ)BRRIouKQK7pl%`2f)>+O| zN-_oUHxLJJ&en2()*z8NJUj<@GDBGst{{PY?^M-G*@1}wzgl> z)Y20t*mvGvVym~n_AX84S+adItX%DQy6(G|(c1XW%J;5M&t^{=R?7G%e$4wDR(Ni4 zbTPjbK>bn)U^EinI!eDHVNQN0yI$$eC=X5nQwy|zT?13BO&U42PtOuP_SD_#CtOBo zwu2c$KED@$9CHn5K|_*zhK^-5AR`B{W-I7U>XFpzRVF(e;xKp?T?2o=D9Abn1o5kpq=OmB*npXH5s>qfR4 zj?RvUnVZng_3go8X1~Hl`zwZ0qK(2Wmf^KCc*nJmW4GVxw_uZC1~+_Ch@ZACpsBB~ zx#L$*`QAkc5y?Q7q?KF6zowL?bw(E9`NSOW*?@a$8nlOB5!x92EhhX<+`R8_AD@hFH4ed+5?eO^ z)zGc<)DCX7)%HZy+o&{KE#ScTq6@E(axKA5@FuPAasqfh{f=^c{degn<^`oUBU|N^(BLftNfQ{RAw(OcqL>%gw`38fd?%@2KLC z&%&ZofV$bo7YPB-Ku^NpNgk;1*#Kmv-X1O?Pr8-o2m0Y{%k~d*+w! zqY!Eo!A>6?&@QIgYShGH&3p>D$l+R-`LrzvvZ0m>WxA%)OiZn?BU7X@P6ZUl`n-!z^ zmigRAQ*}naPk#B%2ZlrXXT0ZgPIP`?ofqjD|MXd-<_CcgL*UP*FO_@~aBH|9w`H zYzu9JPhmi2VbJZh{8^v@-7GE%!=+B)(j6T2+ikdGnrMvq3|}H0B>UbQ`Kd1BrIdIC zH=sEUyuMF**>Y5SBJPVt{c756RFNhi){Ihli6rfSJ5v8_2^c260PWEkG{kb2eIb93#UOqQvs|Ckr^xV7N<)$s4!w-!e zMw_Cgi-`~&q87&yb(Tb=S>kA9;PtVyI=z%JX8y^Ac8>PDPimGwHyuG(k+%72Kjp!PDU#Qp$Ky{r-X1N-owj33p#2Vv4QhWPxUhum`u@rEt?PC>0J2GPAUlpl z30za-B@ZG(RhTuCz=|kqxHL;bTOmMfJ{4Qn{haT^Q)fDgZ{%bp+p4|=HdE3sf?mt_ zm0BphPt-}_0SO(7#v-J6KZ={PHeez9;CQFlN#l&a|7*bdoM`1_Mf{Vww+vR9UdIO(V1i?`Qy>~mwVhSRDvdFg08krqS% zQ_DfZQ2obKA2s8|B__fJBbkK#$5qo`4*Do5+1n>78dj-nRjjq@*BAXX5|p~A46M9$ zD^Uvr(Lr>EkCOPKzb_{+d+uhpzWZST|BVMuN_|;H3x9cG`WrekcD*XddLCEcD!j6` z)|tMw!n7oXvbL@bV@qUbOhCQXRZE#tYF}eQ4TywKxKBb z)_VK`ZN}_Nd*2_%)F9p?#(PSY zliZvcG|#T^6Ldtx+@MaeweRTypMY-~x;d(=XC{{kateV)zf|FQm#I=z6NgeREJ`_9 zX$5Qk%G{=nUJVCe2OFJ!@vTyK;2DA0C`lVoq?QQ6A&PGbdU{&vA)SN?`&bESr?C8M zK;VKX<&)*iOO%X`a86!tvfIs4oKFrzDJC_CHWvk%`0tBVbxmGv);y=Z|FrVam;z4% zC8(3`lIn<;nyY9Ms%DWXDH7`-$m`G37zrV1ORH0w$2X zANeXSlN}AB1LUx?!h8^aEOO~|FF0NTLQn)r6F_L<12MLTSssI6!Qc5_w+TP@_M^wF zERUD&vT^Gek=;u=k>JF0?jooElSQa<22l_zHfQAgh6X<4-^JDKdN3>_VFkhZj2C8`S&AH9NnMFvHJkEV8f+Wh|sou^U?5e5iWvEQ?hZvBU(O@n}NLDdXIH!&cue6$iaMU{3 zCQ^8veS=AZBGucT-XMd~k?@u=wq-}GUR!e=Lz_$5r*tvBIv{B){D5G0>O`#juzp(- zV2iJn;tE;faGr1Va6N0EHGtT2ww@C7tkjtJv*$G{`qV`@S-@w#dpkW9tWD*|J<+H< zOoDpb@WcJI#y|RsR`sQ!C$YiAp5J#({raiJ{Ks-n`x%;!bu*(Q&aF}jx9wSATze#V zFF1~;=GkrmCXp%=5(tsyHC03qpp}k=*(s*VtitNzPNZDkq=ep5y~)kx;9Cnq7Q1MD zwSJyV5!Yj!?`92-_4^7!vs7cLRA_x5vi@Zi?Jrbt(6s*aLvqgcSG$J;_bU&GblsGoL*>%?{7OhyqwtAR1H%_2^A)Vk=u4gB%&iMni?ZfRosnW&YHI`O z#O#CIuoy}K&&_AXdj>J6p$g`|zF0t}_K~sbNKHZ6Wky5wk8#JE0yl8&$nmBxla0^d z8W8j`GkB2t_Tnw8P5IP=NyHaP#ly=9!%xn&OE_7$b+fD@OmMfesG^^kT$w_SQ_fdR zO`1VjHGRY;WZY?@eEe2tHvzx%4=(tA?lt>$%iZpKX?Kksr`gFr9*6F~yRxZ@^E@vsG4SYOPJE zI6jc2(}_~-cnfXWTN35TCO16h7Fobn>k_o2NSz^L0?pdFF)+tVbgA;0F7&v8L4uG{*KRL(r1$7L2xJc? z3{C8$=`J3oyK#5r-3ms#y$=FxnKd%jwJc$0!yy(?Bv{sRv$JtPA?g#q*I0RL2q}wk&=S){abG>|+;D2BTF_ zy}`g$z7Di7hH3^v548^~DO2U+%Hg^FDw156AU0_NQ`Swy7kGXir%Zl*{u3C4w7Bt@ z+O+Zrda!R%mRO_fJ-{5!p-_Wud9KSkexCK|ALT4BQm?k1xfz-HPG8q@Qhs0~p;JJ! zQWlL-0Qez2P6uJnMCuha&-3`^9qHn>!(zbe+6hg%~!8~RQu@$roXAJ9|0g805` zCo1$rGpuvL6@XjGE~c259sqs}tN$QhW>=TwK@Sr|iQ9B)-`byFl~&T{HxgWeV^t+% z(H_$C{jlrzt~an&@&LnOU|u^Yax90v`U-DY)OBxQ+`t=y2fD0&Ya3f$DyJU#jCJQQ z>X6RF{py*TP#lW7-?i9rNRP(N2pLzydm0bfcd=2I7zAcz#dzf2?<{qt7Z*D6nJPd_ z^F2*a*bN!B1`y#;kX-xe?jRWfbikmx%=Ho8dup8qVpeG22^5M6I2vmGn9@lUY*uBTW&G2x5`U~Ny3pdP*opGqGjNU>cCuvK^c{ zgt8Ou+QXRo2Nm*kzEXm_7O|I~}wIv^ic^Y6)sQd-Wba zP4DQG)^Y>`5^s<6%`kMIPXrOk5eFNj;s4sEFq=U)&RL}|PezIQl&9&%>bHlGEQf$A z9ZJK%A}m-nw9=*RSL0WLzxXdM~g;#K+KlVtK=d}6IFsR9%t76yW#N+~IM(~L3gT;~B-~yE1T3~d3=60FeudNo_Lw~6+ut-(Cm0bo& z*KNK=E^LcX~vaw#1MW+2^fmqlD1h)=9 zLp(Camuh~G$l-TAJTe9L$|3PBw5j-(1Hiim&~4F|hwHN1Gd97kyi|HwOApPzy}E@L z&TY~NDigOokcJ@DJn@{!!#eDRjfyP0bH7>ELpB{+ZtgXX;Ytpd^ zBP!Vlqg8bL3GeY<9ZM9L1_T%@f{{D+BZi_>a65To#2fASV{50X#%lBqBI%75G0S0@DE-h;<4PQ9TFl5`2g(aRGvU-GPjiefw`Lj;V6M%9APjgte`n=_ z$`=C2H&NAkt3Bp<8@?sFW!hs`i4J#jEW`m=>y*N7zBNFIfJNwV(i@n>cfxor# zBnQc8;~%p+C;ajcI^QS&=6uMD4pFWi9)s@u_C2r&sC?g7{nDp~Ark7-g|!@OM1|fN zhEE?ioe4A=Yd|5zW!?a=tYAWf*C3-GQs8*I;ej4BnC|8$DM0q>3?|G=~U{gM*{I_1q!O)3#?V@qG&bS7(9BP}2^Xv-nt* zP5<(?@*vtR|GeKgPnJ9`_qt?+xfSAQ(ic#&gQa)A{sdO^RbWv?!~UKRO1tUEE-NwJ z8YY8^V%$kxJ<|;5{#>D7cQoS9xX(-1%t&a5$$lL657(ar_pTWeObmgXhx=^#-q%qG zYQjD#r}uM+SBPH@IIq%)kG|F^Aw38AsSdtFl#tlWt4->UaIE!wwjz*3g8x$R7=hx^ z1hzWLpQ*smTio0%sV$^#>U;bIJ7Q8Xw3n=Wx9DsXs%c{{z07A02@rYz=0VvZk3(1>TkN#+Ta&xS{rU-v*ZO zyWnpt}0qfe)Bqh4qQ9hL>RWAOVlPn4>D{x(;Pbnkj{} zt}lKEH`IIqwGdp9Nl|{+m3SHXZqBMW#-herdp@14VfNaL{Dy9iZy`N(NCUR4q(QM=SH0u&6j z-T`B-(oK4R7avax~6f1s+z4}hOPxdxt3$^9&F#?2%>ipAYZ{knz(9 ztJe?3u#W&n$`%wRmsDdUr$F}Q~C5FlpGQE{Z=d{$+9;?BiE;Y+N zP7cj9GLXkv8?O6;>PZqzi7zR6Ht;KJMgDk612+!dTJviKEr<(;oLfsb`oYt&F*%gu z833Bgy-{a>7w=(NL396=nhMAmaAIX=+9O{EohyaKg@&1}kUv1J0!#1+_j#d@#j*8T zJT3La*#XORH_QE2^?SVVHpSC!2ji#YkbMh{ytmOm7tY|_^1{@2vTTm>r6W2&+cO27 zF5YQfp`2`q6`o?}H%$mtcx5wozNN?+$*Yhd;qCH)I`<${R*Nxr!e}$RrnL0?xX}<$ z0j%XF+rmFTX4RoII73t<@Vg16qdjJPs>f(2Dd_eBS`9aB>M39dd{!Lbm89|F;Ov}b zl?PMznQ6t~j>wv1=<3b2;+Jn-6ExCsF?!a7OuV4t-7~j8NhQ5WnV$EAK6oDvQ#8Eb z0_A)V3TN}A>(r~HazjkHES8Zq@M1wM@GSl%Y*7iW*ILlf<{Zu7fNGX#xHK1#H^zV4 zF$$#c%!`3D@rC!?3h?514mpf>?62|BklaGDf!<0m_!St%Y&A;w~k2?n5&X(=NNRwkRFk18! z&fGzN8k6)4IYp&GG%QVZA6I0`<^BCN6OzgL4e$Bs!?)Qg$u`c~5?kqOj50w_9;Cq@ zkLULsf<-w&ku4{?vuj%FNPlShe()~HOf|F;a$>Ts&Ld{lPl1wBOoOn>W%M=xIZ?uX zlqwb~V8+dXN*k@qU6|nh!|dCBfuKy^k>8Mp+>(P^X%3 z`v{gRbgiKym$sACY0d2e-D*+TVy`WiczW~V@Ap0Zxo;t>HRfh%=mcKrC;`NDX&;nZR-re zG%+_#B62gk2bYDTjz3wUCJ|4AtM~a=68o#m99KWZcTw6bCRKjdHL^9zU3Mf222};= z@9!`V_7Kpu#7*G3X0mvUJ$RroB>48PicZ*V_!Sp$f*8xY-vRx`u6 zz)lIEwFJbRWd&6yQc<$QR$n72ebh%DOod4-+EaL<|$chUi7+EE8}4yqJ&m zg=DH$f5PK&oDt>L+243<4r2Kvbt$HDXWVfk?_L=F%9~UOsu)aUvr^u84iw9BULGAm z0Kc)}lT5aU^1NGfw1wfSzp!ArYS$Y1t!C%1k!E|KE@JbpK6ZH9yO$-^A9ST8RIM+3 zfP+Oa=J7oXHbCT3UnsS+F7J7Ascs6Gp-$e9KNB?o?jnrkz9|SDtU&;pw6CP)fOvY* zSz|k=XBI#0aM7?AK)|-J#IT#BE@{&jn#vrp;>9cYL6(J->Q-`Jv}9)IC6&i)?hgF+ zR*eH?l4+TJbCw_|lGQVQHt~ipyK_fKd|X&-mp?zvI{s~iy2yHGhd$!F%@o16n_18r zMmbST$fQ66QjRn(7*@T{FAHek)lw_}8`T`?fRR&H@{iBxgOSn_SnaL4W5hty<7wY# zdP?%u)72mVsjly+SvIuG@>~w!$CK*90gvy9)({7Sax}^+T$4UIE&;dwnfE2#h46;2 z`Ol7*Li(;*uLfTCKDEWA6yHgiUb{*EDlz$0Z}>pHAMIe1e-M+Go+!ERYxCI#n_i$1 z`kmscH>4%y+7b?2^1H=g1ASb6?ybn(LWJN2T zL4CB7*8t(s)av@6zz2Pn7205A$L9LThqQRbl$drupaFzx(0hzLw78*OAL8SS_qc7D z57Bl5Z?8%fbpD6ARj2etu9M$PWyr(qw*2&s8rd>3AsGucXXEN1vb7Lb0huBQFf^5J(;mn~Y(pfe#~ zF43=gK`ovfDLc=`3%_4NVY=6c?wJTtXr??Xt{i<*epI|tUq^KPX>Y-VER&ImyL@|X zZ!*qx$K)W#`?i-=*BK=fj`M+$2QP8bQlK|t7x}3rlKYWf^d%=D8lJia6=?hq&4)6@ zK%8Kaw+yhEv*3-{ljp{4_#5<2hQn|35jghDgKbYnzgWl(p??&*0f0$V{>A?HE{)GY zlNUCOla=z;=^npSU^5a0T4~7AV~@4WS;6#rl+Vh%*HzmA z{#~T{g8OHU)lnD(p3Hc`B#^;+R*pG>g-n~RCKr0B9I4`iN|VLm7dAxS78TxK>=Ka= zqm>-?s5V`H78Ly4CtwA0E6xc?Nnu*^>9CwCz#@jO&nnBe8bRZI-hsfe#_IOF& z8F3K631e5m3l!aZVDEQ>lBu`cqED)ijhQTDKeC#AU08{jo2kzcsY?CpazeLFlJO5uwT>nFh1e zGav%Czv)Aqy|_0B!<&X4I%UEd8^hxajj6%$oTt1Nt{_7}FYF0_R?Xsc;5^)Sw~wi^ z4wVIR?!Hr+B9kjk*>dIA(sOOqb|>S78D6N==E#TJ!W=3*4|LQ6Av(|VBfxR8XpYVu zD<-eI?20vXPe0mSh?o{bcc(mw(1pa+Fc+Rw&boIPWe0g3QFkRQ9alhqnO_|hnX({DRr*^{jVRmIo`Br~+q{-PNN%?oY-5B!wM%w$mI zImctnWKm?P*%NgEHGj5Rqo(C%7o-5IBjHgxx~#4xjul*vKbXU}`xw#MF_XtC?7e>M z)6V%-FWQQ=?xhbn(^HIWHgam!h4<^J(mp~_S<063lLk8D#a>Qyl5z|^K(<~0nRvV2 z>hMnF76D0-1IKnl(9LyWZ;6#DvZWK*>Ll8`*lAb%vY;Ee@6oHc7vr;)MwXFPRSFV2 zBlby3Tt7B|S~avRWGLAFw?t&iHk@G8SU`a$g}D5L)lL4Ya6>c{()L)XBDR9BIvaOX#U zG_dW($OiA0E-Sw?Bqx0PspFTH$_MbXmRnt4)Ny>~L?%#ZLypD}k7j$ShI?jd;AK&j?+C43ceGBJfgU{5hA`&(YG=ZWP5-(=vYW_@a77SGCF*y) zZBT7Hm@dGUOhmX35>2F@4D7jsKr*FBFfP^ti=%!#s2+gdOGe=pNn_ZpGjDsXdS2*D z6sZjvPU_+2{0}_b0SOP!fJvTEv1w%cFNTtPZH<=!y$ft6XU>Wan%z}EZ3sURDIi>) zAq0B05BWiR{KY9eJ~-c`$*XH(5=4dB?=S>9uaFSlKZj5#s$Wy8hyG1_n|hS{v6e%( z#em_9+hY4-N4Ob)7Yo=9xKU03la8wL`czE`@ib^m@9XdXa{yqBiQR$&MewP07OjZO z3?GcfDk)^H3{bw)548}?G1`Q~Np5z3Blc^MOYVc$InT$Cs9R**11wP&l;fs;&Nuwr z%>ZN$2)x_C#UWcj$M)1=A6c&5dJ(3Q(fE28lu$K97t!h{m!@Vw2|SKg!uChtU=pu# zm$*i|)Zd)_QEtG=DKfb%DZc_#?io;wr6qT*K3zK~ZCK6Fu`}hWY{%ww0vR|m%hGIJ z?~=aQ7MOqmF|oy7+{nOSvd(oL&;{b?XkYX&l$#lpwFzpVCVgOEQ_77;Zoz@HJ_>>< zl^v!P;oJdoBiE)K;Z%PB43Gi6d7#|jl?v<*+D^hew_@)@!G?M-AvZFjHhsxJGG741 z2$<@)r3u-klm1=B+mQeZ7~O_J+qDSxqq~KUj03`mM>3G^v9=dkt6JBfz-q#f)`RR# z2XWM5XC(3MF6|xwyRaANK}%%hd42}4-j8nkU*Oi&Zh)~wlRaQ`AM5G?qP+idPr_G! z5TbSQ_Ifh7JJN`(XRyi3XlyRc=)Mm{x*Fx<0sKH)suOHSD75qDnTcB)I&#Ay<6Hcj zmQ=z{`Zhl+ndiKwoe8(bN+ysTg#(}IdT?pN@MzD$0rZ*q1I`bFv5}^l$JwBt4U~vW zRam}F!hk8ko$e683aI%kLn>2{ym4TS#uveui}?+D{MQd_%4zHwqm1Gx4D-2B-qG+| zV_IxGoF8r38T=tXFsNhb25j9p?p>SK6po|B*%jPtV`m>AVcBe7@BU4amisyw6Fo8E zon?{lhfs1$^Xqy{ZPlblI7vS=IX}LAN)h~am0^7}^pPpXBa7$gXXHM3nH6hd(&cl$ zC%X^&h4z}D7nXaz6Q$`jtBCSwyYWEVLB|Th2$*7^KwS%Hrw2F9R;d93paftl#k<%s zn4kwADKKU+Rp(bfx^emKOeg8{_8M$j5CB3AaQa@xD)Ez|aY=;y>gV1e)9&abn&w~7 z@4}3(uK4YGwK=)$Ts1g8g0$LOd zdW20@7Mn>qbszi2_ny$QJzsum615-My!P^wQU-8`;oSJN~ zE|xL&2g9)k62z#bpbf@xkF%a zqnGfCInNCC-5LmB(_p1uDFk~@LaO<|W)YU>g>o>Y(`db;?;R)7b;JsXo^O@_X!^TH z*RH%4?P%DaP@y7Dzhrea{Eb`v&j1&uBet_QiOnE2%=ZNB+t5|MElc++p877d<7Z)GlnI<3xH3Y}&S?m9&!2 zbj*lthb=}v2cnlIEDb%d?S;i5@Mb19J-LXp!a47rLL@Co8~6> z2tTr`=nUXKtVPu|7|GUb-^{U+3_`Y<;w6a!;DvNad(~_YX72Sar`u&m#(f}(F1!Q_ zKP2|~(R(TH%)7^;XM?xQ(f{1PMpSa`dzTyJ!B1}PaoH{*L@ov%p8`a_lF*|ueMsgS zmB5M>c(YKt!HR%Y^BoQ(Il)*xE72gk(ud{%7@oQn)Ln^jsz~mJdVtEbDTjc5PaOlj z)MlzL7v*je)=$Fdr|ECS@qED>s?SvG3Abq3mjtX8WBy4ht(>~IwlSnE*4qO)GBULd z)X!I&VC8{lYANb-(h2^jc)1KkgR2Nbw z6~Uh|wD!rcvtqhk5qA+)rEcbwqygTs!-~s;&ZF=&5(C+PbWPxq2wOFRfT+#t0Xgc- zYSpXe9QL?jJsDdi3_+;FLUBo2V!RP5(YTdf$OYH*j{!O{KmZ!GU`YLNPD7fuWW&_h zhta#GHMcL}YV|TxY*(~dioSO`GLwd^WD!bc1LH?9Lz7>)x=%xX2vVj&el!cJfT?>6 z-H?4@+Xn}lylc|uCOJ;MVOqrQJd|jwj5RDxM#|%C+dT9!N-M*$!K39)kD`iz|L~f$ zuRr34FON&*s?uSU_4^*uvyFlr%RZSTD9?Dy?-TG=UV&NEf-b4Sxy*Hz`aMH2jkK+9 zkFxQDN7+p*q~Yo>(g8ZZ_g4Z@2$N?4a&9Rhw&-HOkhuRE($sx0BnfCLcS~PhoG~I# zCI2J4ZI%+^o;-7uK#zHT!pEf>k=~$)o)`oY#H5u`X^1hi5UKtY z)?%Rg3|>%t0xc_~dFx8nBW&O_&2e~gzj?W;&IvY)&YEufQ|kkdbd|czVUkC#|B#UK z3n`!LO4&U1MWCl;;2(Ikh{KeUY)3aHCs-ytkzlIJL#S zMWmBdXq7Na?Ghyfp0MDyz{S)zLAV4Ar{5ILI+=O4V>;gVvZ;1<6Q?hOcEOz*t=K22 z5pRXC;a0FcV>8K#hr@1A-@v%R5VE=1pPr2^@XNClP1E0#&Gh%WqwI_}+{8Z3KoV1e zmZj7hMDJejlL}s_(&{GVWx6#th^Wx8y%ASG;PjFMBh<{jLS-%adLz*|(lH=#-)hC8 zF`K8Bi|rj^qZ<$_^5FWWD@am~qD8u1z~w0fyZ1o@FfK~q^%ku=y{1T&Z!J=Iob88T z|J(?77D|@9{N157#|O=RXT?O15j!#Ey`4|mIH-}L0g|TL_ebd$Yx&ugA`+Q*j=uvz ze9gzrt1zeeZQ(a^Z;ybmxW;BvX9t;nJXM5k$RqDFtw7wmg*%^ z%a4_(%HJ#cKD7{mcP1I(ts@OWK|UdM3)YS=rJm(0iSOJ$onhW<;z!R^#TwTc=o@H1 zsLgnizn~*s*{UoC&DKa*WpJ|gQFHapvTKOGy8&iZ{F(&V1cbW3_=^bKY21Bz<&(h; zh=EJx+P9)U=E0UPB%5`pn_nVw*V9nQekTSwdB6Pz z7xeDl&y*I*IJ;6w|6%^#Jb&8+>vw<~B(8g~dUU`=FeH$b=hmss25IN75Wl^9*S%k% zI+B0b8fYn_?hKLY8%=Rn)`rtL2MbgN>?|u=X8<{_-J%8 zI+ZZs-rR3~`U$HCM&?JtnY-nl^HVT&mLMniKOR~eZN+$oM_d(cOz&t*h!0-BG*za* z#eK${u3hCkEsW}6$U@1w_EaF`!R_7cNl*qJ6khae2od{!3}Ob%`p6!oke+ZnIJ>S2 z*xpzmyc5<8V=wrPxU8(S9i-xKXTr@GyE?tk`IaKf_4vajP{@LSkWr7D>$%J4gJrMF z`iR9Un>Q=c*Yc2yJ}=e>C4qDE<;CccGA$dETc!ss78yq_ctoC&@X}O7%sc*+gi$6y z8diIG?#3M4Mp*hm!8OPN6gzLgy0wZEDVjpe|1+n8 za4@bi3X|ai*c>1rRAyhs3;tX*Fo?n;#X7%+bz#pW9ILU zJhw@($}FNH=x5(0^kxV9>ye$%emwEb;M+8NaB|UttAJ_>7H@=nVnnuRQWT0V$-y^CPPJ{DGisal2@8* z%NV(58N(kqjIvSVlJeaCED^H7oJi#>Q63JOcvUyOv zJd8imxlVq*eXi$-e_i+rz8v4@n~9tauTXu*0qE}qE01o5l`2=B($o%R3w(X9>$47q$E?*#J47}{M}$@l3m z|M(~j9`}#mM=!>rh|~L2XYoJZdJ7}~w738J71+;+!Go^g+VPK%DB>hA{vHMRGUQ2^ z#?FQPW3aq5-gp0J6xi&VYTw+NsakM3{~j1NySeBt#eYvuGdBagvV>kz|G6rEeg4gD zhVQ?>pDQZ_mSl%R;nIJc;9|YiU)SQ#DgAH1AZ~%qohT@%9!ifNKKtu({Qryd|DTrs d6Vqn_x)5V}+~;;YjRO8D$*Vsue`Nmpe*tokmLvcG literal 0 HcmV?d00001 From 1b11ee5599ad1ffc87b5208dd8d39c0ac08a7bf4 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Thu, 23 Nov 2023 20:14:41 +1100 Subject: [PATCH 16/25] docs: comment Markdown rendering quirk --- src/report/annotation.gohtml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 793ebbe0..f77b4cfb 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -5,6 +5,9 @@ Expects an instance of AnnotationContext as its context. This template renders _MARKDOWN_, even though it's mostly HTML. This is why there is no indentation: indented output can be rendered differently. +Be careful of whitespace: when newlines surround an inline HTML element, it may +be wrapped in

tag by the Markdown renderer in Buildkite. + */}} {{ $criticalThreshold := .CriticalSeverityThreshold }} {{ $highThreshold := .HighSeverityThreshold }} From 748b1feaf88ccc55a687e758f1e7fb5640e48fc3 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Thu, 23 Nov 2023 23:38:43 +1100 Subject: [PATCH 17/25] docs: increase vulnerability handling documentation --- README.md | 89 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index baa94b3d..7fe264da 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ behaviour. > are set to high values your build will never fail, but details will be > supplied in the annotation. > -> If a finding is irrelevant, or you're waiting on an upstream fix, use an "ignore" configuration file instead: see the [ignore findings](./docs/ignore-findings.md) documentation. +> If a finding is irrelevant, or you're waiting on an upstream fix, use an +> "ignore" configuration file instead: see the [ignore +> findings](./docs/ignore-findings.md) documentation. ## Example @@ -77,7 +79,8 @@ the build is failed. Defaults to 0. Use a sufficiently large number (e.g. 999) to allow the build to always pass. > [!IMPORTANT] -> Prefer an [ignore file](./docs/ignore-findings.md) over setting thresholds if a finding is irrelevant or time to respond is required. +> Prefer an [ignore file](./docs/ignore-findings.md) over setting thresholds if +> a finding is irrelevant or time to respond is required. ### `max-highs` (Optional, string) @@ -86,7 +89,8 @@ build is failed. Defaults to 0. Use a sufficiently large number (e.g. 999) to allow the build to always pass. > [!IMPORTANT] -> Prefer an [ignore file](./docs/ignore-findings.md) over setting thresholds if a finding is irrelevant or time to respond is required. +> Prefer an [ignore file](./docs/ignore-findings.md) over setting thresholds if +> a finding is irrelevant or time to respond is required. ### `image-label` (Optional, string) @@ -124,18 +128,67 @@ for more information. ## FAQ -### I have a vulnerability that isn't resolved yet, but I can wait on fixing. How do I do configure this plugin so I can unblock my builds? - -Refer to how to set your [max-criticals](https://github.com/cultureamp/ecr-scan-results-buildkite-plugin#max-criticals-optional-string), and [max-highs](https://github.com/cultureamp/ecr-scan-results-buildkite-plugin#max-highs-optional-string). - -### Are there guidelines on using thresholds? - -Yes. Changing the `max-criticals` and `max-high` settings should not be taken lightly. - -This option is effectively a deferral of fixing the vulnerability. **Assess the situation first**. If the CVE describes a scenario that aligns with how your project is used, then you should be working to fix it rather than defer it. For help on this, check out the following the steps outlined [here](https://cultureamp.atlassian.net/wiki/spaces/PST/pages/2960916852/Central+SRE+Support+FAQs#I-have-high%2Fcritical-vulnerabilities-for-my-ECR-image%2C-and-its-blocking-my-builds.-What%E2%80%99s-going-on%3F). - -Below are some recommendations if you choose to exercise this option: - -1. Set the thresholds to the number of identified high or critical vulnerabilities. This is so you’re not permitting more vulnerabilities than you should. Especially for those you can fix by updating dependencies or packages. - -2. Set a scheduled reminder for your team to check if a fix is available for the CVE. If a fix is available, address it, and then lower your threshold for the respective vulnerability severity. +### The build is failing for an unresolved vulnerability. How do I do configure this plugin so I can unblock my builds? + +There are two options here: + +1. configure an [ignore file](docs/ignore-findings.md) to tell the plugin to + skip this vulnerability. Set an `until` date to ensure that it is dealt with + in the future. +2. refer to how to set your [max-criticals](#max-criticals-optional-string), and + [max-highs](#max-highs-optional-string) thresholds. + +Out of the two options, the first is far more preferable as it targets the +finding that is causing the problem. Altering a threshold is unlikely to be +rolled back and is indiscriminate about the findings that it will ignore. + +### How do I set my thresholds? _OR_ My build often breaks because of this plugin. Should I change the thresholds? + +Setting the `max-criticals` and `max-high` thresholds requires some thought, and +needs to take into account the risk profile of the company and the service +itself. + +Allowing a container with a critical or high vulnerability to be deployed is not +necessarily wrong, it really depends on the environment of the deployed +application and the nature of the vulnerabilities themselves. + +Consult with your company's internal security teams about the acceptable risk +level for a service if a non-zero threshold is desired, and consider making use +of the [ignore file](docs/ignore-findings.md) configuration to avoid temporary +blockages. Using an ignore entry with an expiry is strongly recommended over +increasing the threshold. + +### What should I think about when ignoring a finding for a period of time? + +Consider the following: + +- Follow the link to read the details of the CVE. Does it impact a component + that is directly (or indirectly) used by your application? +- Reference the CVSS score associated with the vulnerability and look carefully + at the vector via the link. The vector will help inform about how this + vulnerability can affect your system. +- Consider using the CVSS calculator (reached via the vector link) to fill out + the "Environmental" part of the score. The environmental score helps judge the + risks posed in the context of your application deployment environment. This is + likely adjust the base score and assist in your decision making. +- Is a patch or update already available? +- Is this update likely to be made available in an update to the current base + image, or does it exist in a later version of the base image? + +Possible actions: + +1. Update the base image that incorporates the fix. This may be the simplest + option. +2. Remove the dependency from the image, or choose a different base image + without the issue. +3. Add an ignore with an expiry to allow for an update to be published within a + period of time. This is only valid if your corporate standards allow it, and + there is a plan to follow up on this issue in the given time frame. +4. Update the image definition to update the package with the vulnerability. + This can negatively impact image size, and create a future maintenance issue + if not done carefully. Take care to keep the number of packages updated + small, and avoid adding hard-coded versions unless a process exists to keep + them up-to-date. +5. Ignore the finding indefinitely. This will generally only be valid if + dependency both cannot be removed and is not used in a vulnerable fashion. + Your working environment may require special exceptions for this. From 8b8df7429edeafefc43c09188d03b2cb1e51a4c4 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Sun, 26 Nov 2023 23:17:01 +1100 Subject: [PATCH 18/25] fix: use /etc directory instead of home Linux conventions are to configure commands using `/etc/` for general configuration rather than user home directories. This lessens the chance of accidental modification by an agent. --- src/findingconfig/ignores.go | 8 -------- src/main.go | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/findingconfig/ignores.go b/src/findingconfig/ignores.go index 757918e0..abb0529a 100644 --- a/src/findingconfig/ignores.go +++ b/src/findingconfig/ignores.go @@ -29,14 +29,6 @@ func LoadExistingIgnores(filenames []string, clock SystemClock) ([]Ignore, error ignores := []Ignore{} for _, name := range filenames { - if strings.HasPrefix(name, "~/") { - home, err := os.UserHomeDir() - if err != nil { - return nil, fmt.Errorf("user home directory not available: %w", err) - } - name = home + name[1:] - } - if _, err := os.Stat(name); err != nil { continue } diff --git a/src/main.go b/src/main.go index a55826ca..39e43ef2 100644 --- a/src/main.go +++ b/src/main.go @@ -117,8 +117,8 @@ func runCommand(ctx context.Context, pluginConfig Config, agent buildkite.Agent) ".buildkite/ecr-scan-results-ignore.yml", "buildkite/ecr-scan-results-ignore.yaml", "buildkite/ecr-scan-results-ignore.yml", - "~/.ecr-scan-results-ignore.yaml", - "~/.ecr-scan-results-ignore.yml", + "/etc/ecr-scan-results-buildkite-plugin/ignore.yaml", + "/etc/ecr-scan-results-buildkite-plugin/ignore.yml", }, findingconfig.DefaultSystemClock()) if err != nil { return runtimeerrors.NonFatal("could not load finding ignore configuration", err) From 4aab48766871df88b228c4919f4b59641cbe85fc Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:46:05 +1100 Subject: [PATCH 19/25] fix: collapse logic when matching ignore to finding Co-authored-by: Callum Gardner <10970827+ctgardner@users.noreply.github.com> --- src/finding/summary.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/finding/summary.go b/src/finding/summary.go index e7bc69bd..02303d9c 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -93,7 +93,6 @@ func Summarize(findings *types.ImageScanFindings, ignoreConfig []findingconfig.I summary.VulnerabilitySourceUpdatedAt = findings.VulnerabilitySourceUpdatedAt for _, f := range findings.Findings { - var ignore *findingconfig.Ignore detail := findingToDetail(f) index := slices.IndexFunc(ignoreConfig, func(ignore findingconfig.Ignore) bool { @@ -101,15 +100,10 @@ func Summarize(findings *types.ImageScanFindings, ignoreConfig []findingconfig.I }) if index >= 0 { - ignore = &ignoreConfig[index] - } - - detail.Ignore = ignore - - if ignore == nil { - summary.addDetail(detail) - } else { + detail.Ignore = &ignoreConfig[index] summary.addIgnored(detail) + } else { + summary.addDetail(detail) } } From 120cc52c0af0caab732301280b43a728745acd4f Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:56:15 +1100 Subject: [PATCH 20/25] fix: use type alias for severity This is now possible due to API changes up the call chain. --- src/report/annotation.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/report/annotation.go b/src/report/annotation.go index 57abea7a..18e1fcbc 100644 --- a/src/report/annotation.go +++ b/src/report/annotation.go @@ -108,7 +108,7 @@ func sortSeverities(severityCounts map[types.FindingSeverity]finding.SeverityCou // sort severity strings by rank, then alphabetically func compareSeverities(a, b types.FindingSeverity) int { - rank := rankSeverity(string(a)) - rankSeverity(string(b)) + rank := rankSeverity(a) - rankSeverity(b) if rank != 0 { return rank @@ -118,19 +118,19 @@ func compareSeverities(a, b types.FindingSeverity) int { return strings.Compare(string(a), string(b)) } -func rankSeverity(s string) int { - switch s { - case "CRITICAL": +func rankSeverity(f types.FindingSeverity) int { + switch f { + case types.FindingSeverityCritical: return 0 - case "HIGH": + case types.FindingSeverityHigh: return 1 - case "MEDIUM": + case types.FindingSeverityMedium: return 2 - case "LOW": + case types.FindingSeverityLow: return 3 - case "INFORMATIONAL": + case types.FindingSeverityInformational: return 4 - case "UNDEFINED": + case types.FindingSeverityUndefined: return 5 } From 638d8543584f520e32eca27338c82ff23237a92e Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 27 Nov 2023 18:59:14 +1100 Subject: [PATCH 21/25] fix: make summary constructor private --- src/finding/summary.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/finding/summary.go b/src/finding/summary.go index 02303d9c..6214b04e 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -75,7 +75,7 @@ func (s *Summary) updateCount(severity types.FindingSeverity, updateBy SeverityC s.Counts[severity] = counts } -func NewSummary() Summary { +func newSummary() Summary { return Summary{ Counts: map[types.FindingSeverity]SeverityCount{ "CRITICAL": {}, @@ -87,7 +87,7 @@ func NewSummary() Summary { } func Summarize(findings *types.ImageScanFindings, ignoreConfig []findingconfig.Ignore) Summary { - summary := NewSummary() + summary := newSummary() summary.ImageScanCompletedAt = findings.ImageScanCompletedAt summary.VulnerabilitySourceUpdatedAt = findings.VulnerabilitySourceUpdatedAt From 32b0cf5ce1144dcb506005977e3bb0d2b57c2967 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 27 Nov 2023 19:07:09 +1100 Subject: [PATCH 22/25] fix: avoid the unnecessary default to empty The map lookup will return the empty value by default if the key does not exist. --- src/finding/summary.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/finding/summary.go b/src/finding/summary.go index 6214b04e..5c799552 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -64,10 +64,7 @@ func (s *Summary) addIgnored(d Detail) { } func (s *Summary) updateCount(severity types.FindingSeverity, updateBy SeverityCount) { - counts := SeverityCount{} - if c, exists := s.Counts[severity]; exists { - counts = c - } + counts := s.Counts[severity] counts.Ignored += updateBy.Ignored counts.Included += updateBy.Included From bd04f4dd69b265e5595463c207316d2ea1b2d477 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:43:37 +1100 Subject: [PATCH 23/25] doc: removed unhelpful doc comments --- src/finding/summary.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/finding/summary.go b/src/finding/summary.go index 5c799552..a1df906d 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -11,15 +11,10 @@ import ( type Detail struct { // The name associated with the finding, usually a CVE number. - Name string - - URI string - - // The description of the finding. + Name string + URI string Description string - - // The finding severity. - Severity types.FindingSeverity + Severity types.FindingSeverity PackageName string PackageVersion string From e36fa45d71558c24c8c33f3ad2daad1de1da543b Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 27 Nov 2023 22:58:49 +1100 Subject: [PATCH 24/25] refactor: split loadignores function --- src/findingconfig/ignores.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/findingconfig/ignores.go b/src/findingconfig/ignores.go index abb0529a..b22b0ffd 100644 --- a/src/findingconfig/ignores.go +++ b/src/findingconfig/ignores.go @@ -58,6 +58,17 @@ func LoadExistingIgnores(filenames []string, clock SystemClock) ([]Ignore, error // LoadIgnores parses a YAML ignore file from the given location. func LoadIgnores(filename string, clock SystemClock) ([]Ignore, error) { + i, err := readIgnores(filename) + if err != nil { + return nil, err + } + + filtered := filterExpiredEntries(i, clock) + + return filtered, nil +} + +func readIgnores(filename string) ([]Ignore, error) { content, err := os.ReadFile(filename) if err != nil { return nil, err @@ -69,7 +80,11 @@ func LoadIgnores(filename string, clock SystemClock) ([]Ignore, error) { return nil, err } - filtered := slices.DeleteFunc(i.Ignores, func(ignore Ignore) bool { + return i.Ignores, nil +} + +func filterExpiredEntries(ignores []Ignore, clock SystemClock) []Ignore { + filtered := slices.DeleteFunc(ignores, func(ignore Ignore) bool { u := time.Time(ignore.Until) z := u.IsZero() d := !z && clock.UtcNow().After(u) @@ -77,7 +92,7 @@ func LoadIgnores(filename string, clock SystemClock) ([]Ignore, error) { return d }) - return filtered, nil + return filtered } // unmarshalYAML decodes a YAML encoded byte stream into the supplied pointer From c90c99e889d2c325f6faefab3a4a39d3af8785e0 Mon Sep 17 00:00:00 2001 From: James Telfer <792299+jamestelfer@users.noreply.github.com> Date: Mon, 27 Nov 2023 22:59:44 +1100 Subject: [PATCH 25/25] refactor: inline temp vars in filter function These were split into separate declarations to assist initial testing, but this doesn't help readability. --- src/findingconfig/ignores.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/findingconfig/ignores.go b/src/findingconfig/ignores.go index b22b0ffd..2c369426 100644 --- a/src/findingconfig/ignores.go +++ b/src/findingconfig/ignores.go @@ -86,10 +86,7 @@ func readIgnores(filename string) ([]Ignore, error) { func filterExpiredEntries(ignores []Ignore, clock SystemClock) []Ignore { filtered := slices.DeleteFunc(ignores, func(ignore Ignore) bool { u := time.Time(ignore.Until) - z := u.IsZero() - d := !z && clock.UtcNow().After(u) - - return d + return !u.IsZero() && clock.UtcNow().After(u) }) return filtered

CVE SeverityIgnored until +Ignored until Affects CVSS score Vector
CVE-2019-5300 +
+CVE-2019-5300 +
Another vulnerability.
+
Critical
@@ -101,11 +115,15 @@
CVE-2023-100 +
+CVE-2023-100 +
A vulnerability present in some software but isn't that bad.
+
Low -indefinitely +
(indefinitely)
100-package 100-version
-
-CVE-2019-5200 -
Another vulnerability.
-
CVE-2019-5200
Another vulnerability.
Critical 5200-package 5200-version 10.0
-
-CVE-2019-5188 -
A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.
-
CVE-2019-5188
A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.
High e2fsprogs 1.44.1-1ubuntu1.1 4.6
-
-CVE-2019-5300 -
Another vulnerability.
-
CVE-2019-5300
Another vulnerability.
Aa-Bogus-Severity 5300-package 5300-version 10.0
-
-CVE-2019-5200 -
Another vulnerability.
-
CVE-2019-5200
Another vulnerability.
Critical 5200-package 5200-version 10.0
-
-CVE-2019-5188 -
A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.
-
CVE-2019-5188
A code execution vulnerability exists in the directory rehashing functionality of E2fsprogs e2fsck 1.45.4. A specially crafted ext4 directory can cause an out-of-bounds write on the stack, resulting in code execution. An attacker can corrupt a partition to trigger this vulnerability.
High e2fsprogs 1.44.1-1ubuntu1.1 4.6
-
-CVE-2019-5300 -
Another vulnerability.
-
CVE-2019-5300
Another vulnerability.
Critical -
-2023-12-31 -
Ignored to give the base image a chance to be updated
-
2023-12-31
Ignored to give the base image a chance to be updated
5300-package 5300-version 10.0 AV:L/AC:L/Au:N/C:P/I:P/A:P
-
-CVE-2023-100 -
A vulnerability present in some software but isn't that bad.
-
CVE-2023-100
A vulnerability present in some software but isn't that bad.
Low - -
(indefinitely)
- -
(indefinitely)
100-package 100-version 4.0 AV:L/AC:L/Au:N/C:P/I:P/A:P