From 577509bbf92094217ccd00c6d7faa746128435c3 Mon Sep 17 00:00:00 2001 From: kota kanbe Date: Wed, 9 Aug 2017 16:13:07 +0900 Subject: [PATCH] Fix MaxCvssScore logic --- models/vulninfos.go | 44 +++++++++++++++++------------ models/vulninfos_test.go | 61 +++++++++++++++++++++++++++++++--------- 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/models/vulninfos.go b/models/vulninfos.go index edd0d15a..735e89b2 100644 --- a/models/vulninfos.go +++ b/models/vulninfos.go @@ -218,10 +218,11 @@ func (v VulnInfo) Cvss2Scores() (values []CveContentCvss) { values = append(values, CveContentCvss{ Type: "Vendor", Value: Cvss{ - Type: CVSS2, - Score: severityToV2ScoreRoughly(adv.Severity), - Vector: "-", - Severity: strings.ToUpper(adv.Severity), + Type: CVSS2, + Score: severityToV2ScoreRoughly(adv.Severity), + CalculatedBySeverity: true, + Vector: "-", + Severity: strings.ToUpper(adv.Severity), }, }) } @@ -286,7 +287,11 @@ func (v VulnInfo) MaxCvssScore() CveContentCvss { v3Max := v.MaxCvss3Score() v2Max := v.MaxCvss2Score() max := v3Max - if max.Value.Score < v2Max.Value.Score { + if max.Type == Unknown { + return v2Max + } + + if max.Value.Score < v2Max.Value.Score && !v2Max.Value.CalculatedBySeverity { max = v2Max } return max @@ -325,7 +330,7 @@ func (v VulnInfo) MaxCvss2Score() CveContentCvss { // If CVSS score isn't on NVD, RedHat and JVN, use OVAL and advisory Severity. // Convert severity to cvss srore roughly, then returns max severity. - // Only Ubuntu, RedHat and Oracle OVAL has severity data in OVAL. + // Only Ubuntu, RedHat and Oracle have severity data in OVAL. order = []CveContentType{Ubuntu, RedHat, Oracle} for _, ctype := range order { if cont, found := v.CveContents[ctype]; found && 0 < len(cont.Severity) { @@ -334,10 +339,11 @@ func (v VulnInfo) MaxCvss2Score() CveContentCvss { value = CveContentCvss{ Type: ctype, Value: Cvss{ - Type: CVSS2, - Score: score, - Vector: cont.Cvss2Vector, - Severity: cont.Severity, + Type: CVSS2, + Score: score, + CalculatedBySeverity: true, + Vector: cont.Cvss2Vector, + Severity: cont.Severity, }, } } @@ -353,10 +359,11 @@ func (v VulnInfo) MaxCvss2Score() CveContentCvss { value = CveContentCvss{ Type: "Vendor", Value: Cvss{ - Type: CVSS2, - Score: score, - Vector: "-", - Severity: adv.Severity, + Type: CVSS2, + Score: score, + CalculatedBySeverity: true, + Vector: "-", + Severity: adv.Severity, }, } } @@ -384,10 +391,11 @@ const ( // Cvss has CVSS Score type Cvss struct { - Type CvssType - Score float64 - Vector string - Severity string + Type CvssType + Score float64 + CalculatedBySeverity bool + Vector string + Severity string } // Format CVSS Score and Vector diff --git a/models/vulninfos_test.go b/models/vulninfos_test.go index 7502f4ea..99e054ee 100644 --- a/models/vulninfos_test.go +++ b/models/vulninfos_test.go @@ -516,10 +516,10 @@ func TestCvss2Scores(t *testing.T) { out: nil, }, } - for _, tt := range tests { + for i, tt := range tests { actual := tt.in.Cvss2Scores() if !reflect.DeepEqual(tt.out, actual) { - t.Errorf("\nexpected: %v\n actual: %v\n", tt.out, actual) + t.Errorf("[%d] expected: %v\n actual: %v\n", i, tt.out, actual) } } } @@ -575,9 +575,10 @@ func TestMaxCvss2Scores(t *testing.T) { out: CveContentCvss{ Type: Ubuntu, Value: Cvss{ - Type: CVSS2, - Score: 8.9, - Severity: "HIGH", + Type: CVSS2, + Score: 8.9, + CalculatedBySeverity: true, + Severity: "HIGH", }, }, }, @@ -595,10 +596,10 @@ func TestMaxCvss2Scores(t *testing.T) { }, }, } - for _, tt := range tests { + for i, tt := range tests { actual := tt.in.MaxCvss2Score() if !reflect.DeepEqual(tt.out, actual) { - t.Errorf("\nexpected: %v\n actual: %v\n", tt.out, actual) + t.Errorf("[%d] expected: %v\n actual: %v\n", i, tt.out, actual) } } } @@ -742,6 +743,7 @@ func TestMaxCvssScores(t *testing.T) { }, }, }, + //2 { in: VulnInfo{ CveContents: CveContents{ @@ -754,12 +756,14 @@ func TestMaxCvssScores(t *testing.T) { out: CveContentCvss{ Type: Ubuntu, Value: Cvss{ - Type: CVSS2, - Score: 8.9, - Severity: "HIGH", + Type: CVSS2, + Score: 8.9, + CalculatedBySeverity: true, + Severity: "HIGH", }, }, }, + //3 { in: VulnInfo{ CveContents: CveContents{ @@ -782,6 +786,7 @@ func TestMaxCvssScores(t *testing.T) { }, }, }, + //4 { in: VulnInfo{ DistroAdvisories: []DistroAdvisory{ @@ -792,11 +797,39 @@ func TestMaxCvssScores(t *testing.T) { }, out: CveContentCvss{ Type: "Vendor", + Value: Cvss{ + Type: CVSS2, + Score: 8.9, + CalculatedBySeverity: true, + Vector: "-", + Severity: "HIGH", + }, + }, + }, + { + in: VulnInfo{ + CveContents: CveContents{ + Ubuntu: { + Type: Ubuntu, + Severity: "MEDIUM", + }, + NVD: { + Type: NVD, + Cvss2Score: 4.0, + }, + }, + DistroAdvisories: []DistroAdvisory{ + { + Severity: "HIGH", + }, + }, + }, + out: CveContentCvss{ + Type: NVD, Value: Cvss{ Type: CVSS2, - Score: 8.9, - Vector: "-", - Severity: "HIGH", + Score: 4, + Severity: "MEDIUM", }, }, }, @@ -806,7 +839,7 @@ func TestMaxCvssScores(t *testing.T) { out: CveContentCvss{ Type: Unknown, Value: Cvss{ - Type: CVSS3, + Type: CVSS2, Score: 0, }, },