From bb3d713b97375ce761c4e5b88f6bca5e95dcc153 Mon Sep 17 00:00:00 2001 From: Christopher Angelo Phillips <32073428+spiffcs@users.noreply.github.com> Date: Fri, 25 Feb 2022 17:06:05 -0500 Subject: [PATCH] cpe generation update (#850) * do not allow empty CPE to be returned as part of a packages list Signed-off-by: Christopher Phillips --- syft/pkg/cataloger/common/cpe/generate.go | 11 +++++-- .../pkg/cataloger/common/cpe/generate_test.go | 32 +++++++++++++++++++ syft/pkg/cpe.go | 4 +-- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/syft/pkg/cataloger/common/cpe/generate.go b/syft/pkg/cataloger/common/cpe/generate.go index db212b860..f8360555d 100644 --- a/syft/pkg/cataloger/common/cpe/generate.go +++ b/syft/pkg/cataloger/common/cpe/generate.go @@ -12,14 +12,17 @@ import ( "github.com/facebookincubator/nvdtools/wfn" ) -func newCPE(product, vendor, version, targetSW string) wfn.Attributes { +func newCPE(product, vendor, version, targetSW string) *wfn.Attributes { cpe := *(wfn.NewAttributesWithAny()) cpe.Part = "a" cpe.Product = product cpe.Vendor = vendor cpe.Version = version cpe.TargetSW = targetSW - return cpe + if pkg.ValidateCPEString(pkg.CPEString(cpe)) != nil { + return nil + } + return &cpe } // Generate Create a list of CPEs for a given package, trying to guess the vendor, product tuple. We should be trying to @@ -43,7 +46,9 @@ func Generate(p pkg.Package) []pkg.CPE { } keys.Add(key) // add a new entry... - cpes = append(cpes, newCPE(product, vendor, p.Version, wfn.Any)) + if cpe := newCPE(product, vendor, p.Version, wfn.Any); cpe != nil { + cpes = append(cpes, *cpe) + } } } diff --git a/syft/pkg/cataloger/common/cpe/generate_test.go b/syft/pkg/cataloger/common/cpe/generate_test.go index 764a64801..b9bcd5186 100644 --- a/syft/pkg/cataloger/common/cpe/generate_test.go +++ b/syft/pkg/cataloger/common/cpe/generate_test.go @@ -620,6 +620,38 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:jenkins_ci:active_directory:2.25.1:*:*:*:*:*:*:*", }, }, + { + name: "regression: special characters in CPE should result in no generation", + p: pkg.Package{ + Name: "bundler", + Version: "2.1.4", + Type: pkg.GemPkg, + FoundBy: "gem-cataloger", + Language: pkg.Ruby, + MetadataType: pkg.GemMetadataType, + Metadata: pkg.GemMetadata{ + Name: "bundler", + Version: "2.1.4", + Authors: []string{ + "jessica lynn suttles", + "stephanie morillo", + "david rodríguez", + "andré medeiros", + }, + }, + }, + expected: []string{ + "cpe:2.3:a:*:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:bundler:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:ruby-lang:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:ruby:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:ruby_lang:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:jessica-lynn-suttles:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:jessica_lynn_suttles:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:stephanie-morillo:bundler:2.1.4:*:*:*:*:*:*:*", + "cpe:2.3:a:stephanie_morillo:bundler:2.1.4:*:*:*:*:*:*:*", + }, + }, } for _, test := range tests { diff --git a/syft/pkg/cpe.go b/syft/pkg/cpe.go index 9c87df709..85290e50e 100644 --- a/syft/pkg/cpe.go +++ b/syft/pkg/cpe.go @@ -34,7 +34,7 @@ func NewCPE(cpeStr string) (CPE, error) { } // ensure that this CPE can be validated after being fully sanitized - if validateCPEString(CPEString(c)) != nil { + if ValidateCPEString(CPEString(c)) != nil { return CPE{}, err } @@ -43,7 +43,7 @@ func NewCPE(cpeStr string) (CPE, error) { return c, nil } -func validateCPEString(cpeStr string) error { +func ValidateCPEString(cpeStr string) error { // We should filter out all CPEs that do not match the official CPE regex // The facebook nvdtools parser can sometimes incorrectly parse invalid CPE strings if !cpeRegex.MatchString(cpeStr) {