From 43b97706fbbf58f882c6d227925d4aab0e505cd0 Mon Sep 17 00:00:00 2001 From: Lucas TESSON Date: Mon, 19 Feb 2024 21:00:00 +0100 Subject: [PATCH] feat(cvss): add CVSS v4.0 support, fix CVSS v2.0 invalid calculator link Signed-off-by: Lucas TESSON --- go.mod | 3 +-- go.sum | 6 ++---- pkg/cve/cve.go | 52 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 61dc06e997df..9410cfc77483 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/cheggaaa/pb/v3 v3.1.5 github.com/go-git/go-git/v5 v5.11.0 - github.com/goark/go-cvss v1.6.7 github.com/golang/protobuf v1.5.4 github.com/google/go-containerregistry v0.19.1 github.com/google/go-github/v58 v58.0.0 @@ -21,6 +20,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 github.com/olekukonko/tablewriter v0.0.5 + github.com/pandatix/go-cvss v0.6.2 github.com/psampaz/go-mod-outdated v0.9.0 github.com/saschagrunert/go-modiff v1.3.5 github.com/sendgrid/rest v2.6.9+incompatible @@ -149,7 +149,6 @@ require ( github.com/go-openapi/swag v0.22.4 // indirect github.com/go-openapi/validate v0.22.3 // indirect github.com/go-piv/piv-go v1.11.0 // indirect - github.com/goark/errs v1.3.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect diff --git a/go.sum b/go.sum index 7a2772734c19..c3d4183d6e16 100644 --- a/go.sum +++ b/go.sum @@ -401,10 +401,6 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEe github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/goark/errs v1.3.2 h1:ifccNe1aK7Xezt4XVYwHUqalmnfhuphnEvh3FshCReQ= -github.com/goark/errs v1.3.2/go.mod h1:ZsQucxaDFVfSB8I99j4bxkDRfNOrlKINwg72QMuRWKw= -github.com/goark/go-cvss v1.6.7 h1:9R/cx8+lv17uFS1RKYNmEfYqEJwWgF26F4g7hK38jEw= -github.com/goark/go-cvss v1.6.7/go.mod h1:qsmYCGTQnQqW/Lq1Z3lRCEarKD++nx7C+KgsG05MhDA= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -708,6 +704,8 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/package-url/packageurl-go v0.1.1-0.20220203205134-d70459300c8a h1:tkTSd1nhioPqi5Whu3CQ79UjPtaGOytqyNnSCVOqzHM= github.com/package-url/packageurl-go v0.1.1-0.20220203205134-d70459300c8a/go.mod h1:uQd4a7Rh3ZsVg5j0lNyAfyxIeGde9yrlhjF78GzeW0c= +github.com/pandatix/go-cvss v0.6.2 h1:TFiHlzUkT67s6UkelHmK6s1INKVUG7nlKYiWWDTITGI= +github.com/pandatix/go-cvss v0.6.2/go.mod h1:jDXYlQBZrc8nvrMUVVvTG8PhmuShOnKrxP53nOFkt8Q= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= diff --git a/pkg/cve/cve.go b/pkg/cve/cve.go index d5989957aa88..6153ff145c0c 100644 --- a/pkg/cve/cve.go +++ b/pkg/cve/cve.go @@ -20,8 +20,12 @@ import ( "errors" "fmt" "regexp" + "strings" - cvss "github.com/goark/go-cvss/v3/metric" + gocvss20 "github.com/pandatix/go-cvss/20" + gocvss30 "github.com/pandatix/go-cvss/30" + gocvss31 "github.com/pandatix/go-cvss/31" + gocvss40 "github.com/pandatix/go-cvss/40" ) // CVE Information of a linked CVE vulnerability @@ -91,19 +95,41 @@ func (cve *CVE) Validate() (err error) { return errors.New("string CVSS vector missing from CVE data") } - var bm cvss.Metrics - // Parse the vector string to make sure it is well formed - if len(cve.CVSSVector) == 44 { - bm, err = cvss.NewBase().Decode(cve.CVSSVector) - } else { - bm, err = cvss.NewTemporal().Decode(cve.CVSSVector) - } - if err != nil { - return fmt.Errorf("parsing CVSS vector string: %w", err) + switch { + default: // CVSS v2.0 has no prefix + _, err := gocvss20.ParseVector(cve.CVSSVector) + if err != nil { + return fmt.Errorf("parsing CVSS vector string: %w", err) + } + // FIRST ORG has no calculator for CVSS v2.0 + + case strings.HasPrefix(cve.CVSSVector, "CVSS:3.0"): + _, err := gocvss30.ParseVector(cve.CVSSVector) + if err != nil { + return fmt.Errorf("parsing CVSS vector string: %w", err) + } + cve.CalcLink = fmt.Sprintf( + "https://www.first.org/cvss/calculator/3.0#%s", cve.CVSSVector, + ) + + case strings.HasPrefix(cve.CVSSVector, "CVSS:3.1"): + _, err := gocvss31.ParseVector(cve.CVSSVector) + if err != nil { + return fmt.Errorf("parsing CVSS vector string: %w", err) + } + cve.CalcLink = fmt.Sprintf( + "https://www.first.org/cvss/calculator/3.1#%s", cve.CVSSVector, + ) + + case strings.HasPrefix(cve.CVSSVector, "CVSS:4.0"): + _, err := gocvss40.ParseVector(cve.CVSSVector) + if err != nil { + return fmt.Errorf("parsing CVSS vector string: %w", err) + } + cve.CalcLink = fmt.Sprintf( + "https://www.first.org/cvss/calculator/4.0#%s", cve.CVSSVector, + ) } - cve.CalcLink = fmt.Sprintf( - "https://www.first.org/cvss/calculator/%s#%s", bm.BaseMetrics().Ver.String(), cve.CVSSVector, - ) if cve.CVSSScore == 0 { return errors.New("missing CVSS score from CVE data")