aboutsummaryrefslogtreecommitdiff
path: root/cvss
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2022-02-07 12:09:55 -0500
committerPaul Duncan <pabs@pablotron.org>2022-02-07 12:09:55 -0500
commite24e6af76a1dcd64889f47e3fae03d7c3fa6f7a3 (patch)
tree04f33d91e46527bf6442316bc65f92d8d5fa9fe3 /cvss
parentc1982a2eaf4599e1ee7b822373262e8151bfc099 (diff)
downloadcvez-e24e6af76a1dcd64889f47e3fae03d7c3fa6f7a3.tar.bz2
cvez-e24e6af76a1dcd64889f47e3fae03d7c3fa6f7a3.zip
cvss: add score severity and tests
Diffstat (limited to 'cvss')
-rw-r--r--cvss/score.go30
-rw-r--r--cvss/score_test.go48
2 files changed, 78 insertions, 0 deletions
diff --git a/cvss/score.go b/cvss/score.go
index e6a6faa..94a15a5 100644
--- a/cvss/score.go
+++ b/cvss/score.go
@@ -30,3 +30,33 @@ func (s Score) String() string {
func (s Score) Float() float32 {
return float32(s) / 10.0
}
+
+// Score to severity mapping.
+var scoreSeverities = []struct {
+ min uint8 // min score (inclusive)
+ max uint8 // max score (inclusive)
+ severity Severity // severity
+} {
+ { 0, 0, None },
+ { 1, 39, Low },
+ { 40, 69, Medium },
+ { 70, 89, High },
+ { 90, 100, Critical },
+}
+
+// Return score severity.
+//
+// Returns Unknown if the score does not map to a known severity.
+//
+// Score severity is based on mapping from section 5 of CVSS 3.1
+// specification.
+func (s Score) Severity() Severity {
+ for _, row := range(scoreSeverities) {
+ if uint8(s) >= row.min && uint8(s) <= row.max {
+ return row.severity
+ }
+ }
+
+ // return unknown severity
+ return Unknown
+}
diff --git a/cvss/score_test.go b/cvss/score_test.go
index d35c4c8..5bff327 100644
--- a/cvss/score_test.go
+++ b/cvss/score_test.go
@@ -90,3 +90,51 @@ func TestScoreFloat(t *testing.T) {
})
}
}
+
+func TestScoreSeverity(t *testing.T) {
+ passTests := []struct {
+ val float64
+ exp Severity
+ } {
+ { 0.0, None },
+ { 0.1, Low },
+ { 3.9, Low },
+ { 4.0, Medium },
+ { 6.9, Medium },
+ { 7.0, High },
+ { 8.9, High },
+ { 9.0, Critical },
+ { 10.0, Critical },
+ }
+
+ for _, test := range(passTests) {
+ t.Run(strconv.FormatFloat(test.val, 'f', 2, 64), func(t *testing.T) {
+ s, err := NewScore(test.val)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ got := s.Severity()
+ if got != test.exp {
+ t.Errorf("got \"%s\", exp \"%s\"", got, test.exp)
+ }
+ })
+ }
+
+ failTests := []struct {
+ val Score
+ exp Severity
+ } {
+ { Score(uint8(110)), Unknown },
+ }
+
+ for _, test := range(failTests) {
+ t.Run(test.val.String(), func(t *testing.T) {
+ got := test.val.Severity()
+ if got != test.exp {
+ t.Errorf("got \"%s\", exp \"%s\"", got, test.exp)
+ }
+ })
+ }
+}