diff --git a/src/finding/summary.go b/src/finding/summary.go index 729af9f0..3f629d58 100644 --- a/src/finding/summary.go +++ b/src/finding/summary.go @@ -31,8 +31,9 @@ type Detail struct { } type CVSSScore struct { - Score string - Vector string + Score string + Vector string + VectorURL string } type SeverityCount struct { @@ -128,6 +129,9 @@ func findingToDetail(finding types.ImageScanFinding) Detail { uri = fixFindingURI(name, uri) + cvss2Vector := findingAttributeValue(finding, "CVSS2_VECTOR") + cvss2VectorURL := cvss2VectorURL(cvss2Vector) + return Detail{ Name: name, URI: uri, @@ -136,8 +140,9 @@ func findingToDetail(finding types.ImageScanFinding) Detail { PackageName: findingAttributeValue(finding, "package_name"), PackageVersion: findingAttributeValue(finding, "package_version"), CVSS2: CVSSScore{ - Score: findingAttributeValue(finding, "CVSS2_SCORE"), - Vector: findingAttributeValue(finding, "CVSS2_VECTOR"), + Score: findingAttributeValue(finding, "CVSS2_SCORE"), + Vector: cvss2Vector, + VectorURL: cvss2VectorURL, }, } } @@ -170,3 +175,12 @@ func fixFindingURI(name string, uri string) string { return correctedURI } + +func cvss2VectorURL(cvss2Vector string) string { + cvss2VectorURL := "" + if cvss2Vector != "" { + cvss2VectorURL = "https://nvd.nist.gov/vuln-metrics/cvss/v2-calculator?vector=" + + url.QueryEscape("("+cvss2Vector+")") + } + return cvss2VectorURL +} diff --git a/src/finding/summary_test.go b/src/finding/summary_test.go index 167221cc..d3d6e1d7 100644 --- a/src/finding/summary_test.go +++ b/src/finding/summary_test.go @@ -3,6 +3,7 @@ package finding_test import ( "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" @@ -62,6 +63,42 @@ func TestSummarize(t *testing.T) { Ignored: []finding.Detail{}, }), }, + { + name: "findings with CVSS2 scores", + data: types.ImageScanFindings{ + Findings: []types.ImageScanFinding{ + fscore("CVE-2019-5188", "HIGH", "1.2", "AV:L/AC:L/Au:N/C:P/I:P/A:P"), + fscore("INVALID-CVE", "CRITICAL", "", ""), + fscore("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}, + }, + Details: []finding.Detail{ + { + Name: "CVE-2019-5188", + Severity: types.FindingSeverity("HIGH"), + CVSS2: finding.CVSSScore{ + Score: "1.2", + Vector: "AV:L/AC:L/Au:N/C:P/I:P/A:P", + VectorURL: "https://nvd.nist.gov/vuln-metrics/cvss/v2-calculator?vector=%28AV%3AL%2FAC%3AL%2FAu%3AN%2FC%3AP%2FI%3AP%2FA%3AP%29", + }, + }, + { + Name: "INVALID-CVE", + Severity: types.FindingSeverity("CRITICAL"), + }, + { + Name: "CVE-2019-5189", + Severity: types.FindingSeverity("HIGH"), + }, + }, + Ignored: []finding.Detail{}, + }), + }, { name: "findings with no ignores", data: types.ImageScanFindings{ @@ -160,6 +197,17 @@ func fu(name string, severity types.FindingSeverity, uri string) types.ImageScan } } +func fscore(name string, severity types.FindingSeverity, cvss2 string, vector string) types.ImageScanFinding { + return types.ImageScanFinding{ + Name: &name, + Severity: severity, + Attributes: []types.Attribute{ + {Key: aws.String("CVSS2_SCORE"), Value: &cvss2}, + {Key: aws.String("CVSS2_VECTOR"), Value: &vector}, + }, + } +} + func i(id string) findingconfig.Ignore { return findingconfig.Ignore{ID: id} } diff --git a/src/report/annotation.gohtml b/src/report/annotation.gohtml index 0bda558e..4bebbe88 100644 --- a/src/report/annotation.gohtml +++ b/src/report/annotation.gohtml @@ -42,6 +42,9 @@ be wrapped in
tag by the Markdown renderer in Buildkite.
{{ define "findingName" }}{{ if .Description }}{{ template "findingNameLink" . }}
tag by the Markdown renderer in Buildkite.
tag by the Markdown renderer in Buildkite.
tag by the Markdown renderer in Buildkite.
scan completed: | source updated: diff --git a/src/report/testdata/TestReports/no_vulnerabilities.golden b/src/report/testdata/TestReports/no_vulnerabilities.golden index 357825e5..c56dd03c 100644 --- a/src/report/testdata/TestReports/no_vulnerabilities.golden +++ b/src/report/testdata/TestReports/no_vulnerabilities.golden @@ -13,6 +13,7 @@ +
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 80e5bb98..586e4162 100644
--- a/src/report/testdata/TestReports/some_findings_ignored.golden
+++ b/src/report/testdata/TestReports/some_findings_ignored.golden
@@ -44,6 +44,7 @@
+
Vulnerability details
CVE
Severity
Affects
-CVSS score
-Vector
+CVSS2 score (vector)
CVE-2019-5200
Critical
5200-package 5200-version
-10.0
-AV:L/AC:L/Au:N/C:P/I:P/A:P
+10.0 (AV:L/AC:L/Au:N/C:P/I:P/A:P)
@@ -85,8 +83,7 @@
CVE-2019-5188
High
e2fsprogs 1.44.1-1ubuntu1.1
-4.6
-AV:L/AC:L/Au:N/C:P/I:P/A:P
+4.6 (AV:L/AC:L/Au:N/C:P/I:P/A:P)
Severity
Ignored until
Affects
-CVSS score
-Vector
+CVSS2 score (vector)
@@ -94,8 +91,7 @@
Critical
2023-12-31
5300-package 5300-version
-10.0
-AV:L/AC:L/Au:N/C:P/I:P/A:P
+10.0 (AV:L/AC:L/Au:N/C:P/I:P/A:P)
@@ -103,8 +99,7 @@
Low
100-package 100-version
-4.0
-AV:L/AC:L/Au:N/C:P/I:P/A:P
+4.0 (AV:L/AC:L/Au:N/C:P/I:P/A:P)