diff --git a/changes/bug-8145-utm.app-bad-cpe-matching b/changes/bug-8145-utm.app-bad-cpe-matching new file mode 100644 index 0000000000..ffc0ca9f8b --- /dev/null +++ b/changes/bug-8145-utm.app-bad-cpe-matching @@ -0,0 +1 @@ +* Fixed bug with our CPE matching process. UTM.app was matching to the wrong CPE. \ No newline at end of file diff --git a/server/vulnerabilities/nvd/cpe.go b/server/vulnerabilities/nvd/cpe.go index ff9d6baee1..62aabb793e 100644 --- a/server/vulnerabilities/nvd/cpe.go +++ b/server/vulnerabilities/nvd/cpe.go @@ -208,6 +208,8 @@ func CPEFromSoftware(db *sqlx.DB, software *fleet.Software, translations CPETran } var results []IndexedCPEItem + var match *IndexedCPEItem + err = db.Select(&results, stm, args...) if err == sql.ErrNoRows { return "", nil @@ -217,44 +219,46 @@ func CPEFromSoftware(db *sqlx.DB, software *fleet.Software, translations CPETran return "", fmt.Errorf("getting cpes for: %s: %w", software.Name, err) } - for _, item := range results { - if !item.Deprecated { - hasAllTerms := true + for i, item := range results { + hasAllTerms := true - sName := strings.ToLower(software.Name) - for _, sN := range strings.Split(item.Product, "_") { - hasAllTerms = hasAllTerms && strings.Index(sName, sN) != -1 + sName := strings.ToLower(software.Name) + for _, sN := range strings.Split(item.Product, "_") { + hasAllTerms = hasAllTerms && strings.Index(sName, sN) != -1 + } + + sVendor := strings.ToLower(software.Vendor) + sBundle := strings.ToLower(software.BundleIdentifier) + for _, sV := range strings.Split(item.Vendor, "_") { + if sVendor != "" { + hasAllTerms = hasAllTerms && strings.Index(sVendor, sV) != -1 } - sVendor := strings.ToLower(software.Vendor) - sBundle := strings.ToLower(software.BundleIdentifier) - for _, sV := range strings.Split(item.Vendor, "_") { - if sVendor != "" { - hasAllTerms = hasAllTerms && strings.Index(sVendor, sV) != -1 - } - - if sBundle != "" { - hasAllTerms = hasAllTerms && strings.Index(sBundle, sV) != -1 - } + if sBundle != "" { + hasAllTerms = hasAllTerms && strings.Index(sBundle, sV) != -1 } + } - if !hasAllTerms { - continue - } - - return item.FmtStr(software), nil + if hasAllTerms { + match = &results[i] + break } } - // try to find a non-deprecated cpe by looking up deprecated_by - for _, item := range results { - deprecatedItem := item - for { - var deprecation IndexedCPEItem + if match != nil { + if !match.Deprecated { + return match.FmtStr(software), nil + } - err = db.Get( - &deprecation, - ` + // try to find a non-deprecated cpe by looking up deprecated_by + for _, item := range results { + deprecatedItem := item + for { + var deprecation IndexedCPEItem + + err = db.Get( + &deprecation, + ` SELECT rowid, product, @@ -267,20 +271,21 @@ func CPEFromSoftware(db *sqlx.DB, software *fleet.Software, translations CPETran SELECT cpe23 FROM deprecated_by d WHERE d.cpe_id = ? ) `, - deprecatedItem.ID, - ) - if err == sql.ErrNoRows { - break - } - if err != nil { - return "", fmt.Errorf("getting deprecation: %w", err) - } - if deprecation.Deprecated { - deprecatedItem = deprecation - continue - } + deprecatedItem.ID, + ) + if err == sql.ErrNoRows { + break + } + if err != nil { + return "", fmt.Errorf("getting deprecation: %w", err) + } + if deprecation.Deprecated { + deprecatedItem = deprecation + continue + } - return deprecation.FmtStr(software), nil + return deprecation.FmtStr(software), nil + } } } } diff --git a/server/vulnerabilities/nvd/cpe_test.go b/server/vulnerabilities/nvd/cpe_test.go index 28f818483a..562bc07139 100644 --- a/server/vulnerabilities/nvd/cpe_test.go +++ b/server/vulnerabilities/nvd/cpe_test.go @@ -712,7 +712,7 @@ func TestCPEFromSoftwareIntegration(t *testing.T) { Version: "2.37.1", Vendor: "The Git Development Community", BundleIdentifier: "", - }, cpe: "cpe:2.3:a:git:git:2.37.1:*:*:*:*:windows:*:*", + }, cpe: "cpe:2.3:a:git-scm:git:2.37.1:*:*:*:*:windows:*:*", }, { software: fleet.Software{ @@ -1128,6 +1128,14 @@ func TestCPEFromSoftwareIntegration(t *testing.T) { BundleIdentifier: "", }, cpe: "cpe:2.3:a:python:urllib3:1.26.5:*:*:*:*:python:*:*", }, + { + software: fleet.Software{ + Name: "UTM.app", + Source: "apps", + Version: "3.2.4", + BundleIdentifier: "com.utmapp.UTM", + }, cpe: "", + }, } nettest.Run(t)