From 8503ad33ebc2046af80262d2f687e9ad92ae8b26 Mon Sep 17 00:00:00 2001 From: Chen Keinan Date: Tue, 22 Jun 2021 16:58:41 +0300 Subject: [PATCH 1/3] severity and cvss metrics support. --- client/client_test.go | 4 ++-- osv/json.go | 2 ++ osv/json_test.go | 1 + report/report.go | 9 ++++++++- report/utils.go | 47 +++++++++++++++++++++++++++++++++++++++++++ report/utils_test.go | 31 ++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 report/utils.go create mode 100644 report/utils_test.go diff --git a/client/client_test.go b/client/client_test.go index c9c1eeb7..c6f2da46 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -19,13 +19,13 @@ import ( var testVuln1 string = `[ {"ID":"ID1","Package":{"Name":"golang.org/example/one","Ecosystem":"go"}, "Summary":"", - "Severity":2,"Affects":{"Ranges":[{"Type":"SEMVER","Introduced":"","Fixed":"v2.2.0"}]}, + "Severity":"High","Affects":{"Ranges":[{"Type":"SEMVER","Introduced":"","Fixed":"v2.2.0"}]}, "ecosystem_specific":{"Symbols":["some_symbol_1"] }}]` var testVuln2 string = `[ {"ID":"ID2","Package":{"Name":"golang.org/example/two","Ecosystem":"go"}, "Summary":"", - "Severity":2,"Affects":{"Ranges":[{"Type":"SEMVER","Introduced":"","Fixed":"v2.1.0"}]}, + "Severity":"High","Affects":{"Ranges":[{"Type":"SEMVER","Introduced":"","Fixed":"v2.1.0"}]}, "ecosystem_specific":{"Symbols":["some_symbol_2"] }}]` diff --git a/osv/json.go b/osv/json.go index 1ee0867f..d128838b 100644 --- a/osv/json.go +++ b/osv/json.go @@ -122,6 +122,7 @@ type Entry struct { ID string `json:"id"` Published time.Time `json:"published"` Modified time.Time `json:"modified"` + Severity string `json:"severity,omitempty"` Withdrawn *time.Time `json:"withdrawn,omitempty"` Aliases []string `json:"aliases,omitempty"` Package Package `json:"package"` @@ -144,6 +145,7 @@ func Generate(id string, url string, r report.Report) []Entry { ID: id, Published: r.Published, Modified: lastModified, + Severity: report.CvssScoreToSeverity(r.CVEMetadata.CVSSMeta), Withdrawn: r.Withdrawn, Package: Package{ Name: importPath, diff --git a/osv/json_test.go b/osv/json_test.go index 39bfa5de..7341beb8 100644 --- a/osv/json_test.go +++ b/osv/json_test.go @@ -43,6 +43,7 @@ func TestGenerate(t *testing.T) { Commit: "commit", Context: []string{"issue-a", "issue-b"}, }, + CVEMetadata:&report.CVEMeta{ID: "CVE-2020-1234"}, } want := []Entry{ diff --git a/report/report.go b/report/report.go index a400a005..8875db8e 100644 --- a/report/report.go +++ b/report/report.go @@ -27,7 +27,13 @@ type Links struct { type CVEMeta struct { ID string `yaml:",omitempty"` CWE string `yaml:",omitempty"` - Description string `yaml:",omitempty"` + Description string `yaml:",omitempty"` + CVSSMeta *CVSS `yaml:",omitempty"` +} +type CVSS struct { + Version string `yaml:",omitempty"` + BaseScore float32 `yaml:",omitempty"` + Vector string `yaml:",omitempty"` } type Report struct { @@ -59,3 +65,4 @@ type Report struct { Links Links `yaml:",omitempty"` CVEMetadata *CVEMeta `yaml:"cve_metadata,omitempty"` } + diff --git a/report/utils.go b/report/utils.go new file mode 100644 index 00000000..4339e91e --- /dev/null +++ b/report/utils.go @@ -0,0 +1,47 @@ +package report + +//CvssScoreToSeverity calculate severity by cvss version and score +//accept cvss version and score , return severity +func CvssScoreToSeverity(cvss *CVSS) string { + if cvss == nil { + return "" + } + switch cvss.Version { + case "v2": + return cvssV2SeverityByScore(cvss.BaseScore) + case "v3": + return cvssV3SeverityByScore(cvss.BaseScore) + default: + return "" + } +} + +func cvssV3SeverityByScore(score float32) string { + switch { + case score == 0.0: + return "None" + case score >= 0.1 && score <= 3.9: + return "Low" + case score >= 4.0 && score <= 6.9: + return "Medium" + case score >= 7.0 && score <= 8.9: + return "High" + case score >= 9.0 && score <= 10.0: + return "Critical" + default: + return "" + } +} + +func cvssV2SeverityByScore(score float32) string { + switch { + case score >= 0.0 && score <= 3.9: + return "Low" + case score >= 4.0 && score <= 6.9: + return "Medium" + case score >= 7.0 && score <= 10.0: + return "High" + default: + return "None" + } +} diff --git a/report/utils_test.go b/report/utils_test.go new file mode 100644 index 00000000..b66d8fe0 --- /dev/null +++ b/report/utils_test.go @@ -0,0 +1,31 @@ +package report + +import "testing" + +func TestReverseString1(t *testing.T) { + tests := []struct { + name string + version string + baseScore float32 + want string + }{ + {name: "Low v2", version: "v2", baseScore: 1.0, want: "Low"}, + {name: "Medium v2", version: "v2", baseScore: 4.0, want: "Medium"}, + {name: "High v2", version: "v2", baseScore: 7.0, want: "High"}, + {name: "Non Existing score v2", version: "v2", baseScore: 12.0, want: ""}, + {name: "None v3", version: "v3", baseScore: 0.0, want: "None"}, + {name: "low v3", version: "v3", baseScore: 1.0, want: "Low"}, + {name: "Medium v3", version: "v3", baseScore: 4.0, want: "Medium"}, + {name: "High v3", version: "v3", baseScore: 7.0, want: "High"}, + {name: "Critical v3", version: "v3", baseScore: 9.0, want: "Critical"}, + {name: "Non Existing score v3", version: "v3", baseScore: 12.0, want: ""}, + {name: "Non existing version", version: "v1", baseScore: 9.0, want: ""}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := CvssScoreToSeverity(&CVSS{Version: tt.version, BaseScore: tt.baseScore}); got != tt.want { + t.Errorf("CvssScoreToSeverity() = %v, want %v", got, tt.want) + } + }) + } +} From 915b0b3bab22a2eb755ee1a0cf20052e2eeee39b Mon Sep 17 00:00:00 2001 From: Chen Keinan Date: Wed, 23 Jun 2021 13:07:39 +0300 Subject: [PATCH 2/3] feat: refactor cvss property name --- report/report.go | 6 +++--- report/utils.go | 4 ++-- report/utils_test.go | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/report/report.go b/report/report.go index 8875db8e..6fed5404 100644 --- a/report/report.go +++ b/report/report.go @@ -31,9 +31,9 @@ type CVEMeta struct { CVSSMeta *CVSS `yaml:",omitempty"` } type CVSS struct { - Version string `yaml:",omitempty"` - BaseScore float32 `yaml:",omitempty"` - Vector string `yaml:",omitempty"` + Version string `yaml:",omitempty"` + Score float32 `yaml:",omitempty"` + Vector string `yaml:",omitempty"` } type Report struct { diff --git a/report/utils.go b/report/utils.go index 4339e91e..3dde9f53 100644 --- a/report/utils.go +++ b/report/utils.go @@ -8,9 +8,9 @@ func CvssScoreToSeverity(cvss *CVSS) string { } switch cvss.Version { case "v2": - return cvssV2SeverityByScore(cvss.BaseScore) + return cvssV2SeverityByScore(cvss.Score) case "v3": - return cvssV3SeverityByScore(cvss.BaseScore) + return cvssV3SeverityByScore(cvss.Score) default: return "" } diff --git a/report/utils_test.go b/report/utils_test.go index b66d8fe0..efb4e1cc 100644 --- a/report/utils_test.go +++ b/report/utils_test.go @@ -23,7 +23,7 @@ func TestReverseString1(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := CvssScoreToSeverity(&CVSS{Version: tt.version, BaseScore: tt.baseScore}); got != tt.want { + if got := CvssScoreToSeverity(&CVSS{Version: tt.version, Score: tt.baseScore}); got != tt.want { t.Errorf("CvssScoreToSeverity() = %v, want %v", got, tt.want) } }) From a9995153cc660ad89299fd69d5801a836a098df7 Mon Sep 17 00:00:00 2001 From: Chen Keinan Date: Wed, 23 Jun 2021 13:14:53 +0300 Subject: [PATCH 3/3] feat: fix test --- osv/json_test.go | 2 +- report/report.go | 5 ++--- report/utils.go | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osv/json_test.go b/osv/json_test.go index 7341beb8..7c5ce2b9 100644 --- a/osv/json_test.go +++ b/osv/json_test.go @@ -43,7 +43,7 @@ func TestGenerate(t *testing.T) { Commit: "commit", Context: []string{"issue-a", "issue-b"}, }, - CVEMetadata:&report.CVEMeta{ID: "CVE-2020-1234"}, + CVEMetadata: &report.CVEMeta{ID: "CVE-2020-1234"}, } want := []Entry{ diff --git a/report/report.go b/report/report.go index 6fed5404..ee1094bb 100644 --- a/report/report.go +++ b/report/report.go @@ -27,8 +27,8 @@ type Links struct { type CVEMeta struct { ID string `yaml:",omitempty"` CWE string `yaml:",omitempty"` - Description string `yaml:",omitempty"` - CVSSMeta *CVSS `yaml:",omitempty"` + Description string `yaml:",omitempty"` + CVSSMeta *CVSS `yaml:",omitempty"` } type CVSS struct { Version string `yaml:",omitempty"` @@ -65,4 +65,3 @@ type Report struct { Links Links `yaml:",omitempty"` CVEMetadata *CVEMeta `yaml:"cve_metadata,omitempty"` } - diff --git a/report/utils.go b/report/utils.go index 3dde9f53..23a3abf1 100644 --- a/report/utils.go +++ b/report/utils.go @@ -42,6 +42,6 @@ func cvssV2SeverityByScore(score float32) string { case score >= 7.0 && score <= 10.0: return "High" default: - return "None" + return "" } }