diff --git a/models/vulninfos.go b/models/vulninfos.go index df371096..6f39c0e5 100644 --- a/models/vulninfos.go +++ b/models/vulninfos.go @@ -534,15 +534,16 @@ func (v VulnInfo) MaxCvss2Score() CveContentCvss { func (v VulnInfo) AttackVector() string { for _, cnt := range v.CveContents { if strings.HasPrefix(cnt.Cvss2Vector, "AV:N") || - strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:N") { + strings.Contains(cnt.Cvss3Vector, "AV:N") { return "AV:N" } else if strings.HasPrefix(cnt.Cvss2Vector, "AV:A") || - strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:A") { + strings.Contains(cnt.Cvss3Vector, "AV:A") { return "AV:A" } else if strings.HasPrefix(cnt.Cvss2Vector, "AV:L") || - strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:L") { + strings.Contains(cnt.Cvss3Vector, "AV:L") { return "AV:L" - } else if strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:P") { + } else if strings.Contains(cnt.Cvss3Vector, "AV:P") { + // no AV:P in CVSS v2 return "AV:P" } } diff --git a/models/vulninfos_test.go b/models/vulninfos_test.go index a186045f..7df060cf 100644 --- a/models/vulninfos_test.go +++ b/models/vulninfos_test.go @@ -1080,3 +1080,86 @@ func TestDistroAdvisories_AppendIfMissing(t *testing.T) { }) } } + +func TestVulnInfo_AttackVector(t *testing.T) { + type fields struct { + CveContents CveContents + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "2.0:N", + fields: fields{ + CveContents: NewCveContents( + CveContent{ + Type: "foo", + Cvss2Vector: "AV:N/AC:L/Au:N/C:C/I:C/A:C", + }, + ), + }, + want: "AV:N", + }, + { + name: "2.0:A", + fields: fields{ + CveContents: NewCveContents( + CveContent{ + Type: "foo", + Cvss2Vector: "AV:A/AC:L/Au:N/C:C/I:C/A:C", + }, + ), + }, + want: "AV:A", + }, + { + name: "2.0:L", + fields: fields{ + CveContents: NewCveContents( + CveContent{ + Type: "foo", + Cvss2Vector: "AV:L/AC:L/Au:N/C:C/I:C/A:C", + }, + ), + }, + want: "AV:L", + }, + + { + name: "3.0:N", + fields: fields{ + CveContents: NewCveContents( + CveContent{ + Type: "foo", + Cvss3Vector: "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + }, + ), + }, + want: "AV:N", + }, + { + name: "3.1:N", + fields: fields{ + CveContents: NewCveContents( + CveContent{ + Type: "foo", + Cvss3Vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", + }, + ), + }, + want: "AV:N", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := VulnInfo{ + CveContents: tt.fields.CveContents, + } + if got := v.AttackVector(); got != tt.want { + t.Errorf("VulnInfo.AttackVector() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/oval/redhat.go b/oval/redhat.go index 9e578c24..cf816278 100644 --- a/oval/redhat.go +++ b/oval/redhat.go @@ -219,12 +219,17 @@ func (o RedHatBase) parseCvss2(scoreVector string) (score float64, vector string // 5.6/CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L func (o RedHatBase) parseCvss3(scoreVector string) (score float64, vector string) { var err error - ss := strings.Split(scoreVector, "/CVSS:3.0/") - if 1 < len(ss) { - if score, err = strconv.ParseFloat(ss[0], 64); err != nil { - return 0, "" + for _, s := range []string{ + "/CVSS:3.0/", + "/CVSS:3.1/", + } { + ss := strings.Split(scoreVector, s) + if 1 < len(ss) { + if score, err = strconv.ParseFloat(ss[0], 64); err != nil { + return 0, "" + } + return score, strings.TrimPrefix(s, "/") + ss[1] } - return score, fmt.Sprintf("CVSS:3.0/%s", ss[1]) } return 0, "" } diff --git a/oval/redhat_test.go b/oval/redhat_test.go index c7d3d849..8d6e2123 100644 --- a/oval/redhat_test.go +++ b/oval/redhat_test.go @@ -59,6 +59,13 @@ func TestParseCvss3(t *testing.T) { vector: "CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", }, }, + { + in: "6.1/CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", + out: out{ + score: 6.1, + vector: "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", + }, + }, { in: "", out: out{ diff --git a/scan/debian_test.go b/scan/debian_test.go index 5a7d1c03..36c0c238 100644 --- a/scan/debian_test.go +++ b/scan/debian_test.go @@ -1,9 +1,9 @@ package scan import ( - "sort" "os" "reflect" + "sort" "testing" "github.com/future-architect/vuls/cache"