mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Consider Author field for wordpress plugins when generating CPEs (#2946)
* enhance wordpress vendor candidates for CPEs Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * encode wordpress plugin target software Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
f966bcfd03
commit
0956753409
@ -129,23 +129,26 @@ func FromDictionaryFind(p pkg.Package) ([]cpe.CPE, bool) {
|
||||
func FromPackageAttributes(p pkg.Package) []cpe.CPE {
|
||||
vendors := candidateVendors(p)
|
||||
products := candidateProducts(p)
|
||||
targetSWs := candidateTargetSw(p)
|
||||
if len(products) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
keys := strset.New()
|
||||
cpes := make([]cpe.Attributes, 0)
|
||||
for _, product := range products {
|
||||
for _, vendor := range vendors {
|
||||
// prevent duplicate entries...
|
||||
key := fmt.Sprintf("%s|%s|%s", product, vendor, p.Version)
|
||||
if keys.Has(key) {
|
||||
continue
|
||||
}
|
||||
keys.Add(key)
|
||||
// add a new entry...
|
||||
if c := newCPE(product, vendor, p.Version, cpe.Any); c != nil {
|
||||
cpes = append(cpes, *c)
|
||||
for _, ts := range targetSWs {
|
||||
for _, product := range products {
|
||||
for _, vendor := range vendors {
|
||||
// prevent duplicate entries...
|
||||
key := fmt.Sprintf("%s|%s|%s|%s", product, vendor, p.Version, ts)
|
||||
if keys.Has(key) {
|
||||
continue
|
||||
}
|
||||
keys.Add(key)
|
||||
// add a new entry...
|
||||
if c := newCPE(product, vendor, p.Version, ts); c != nil {
|
||||
cpes = append(cpes, *c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,6 +165,13 @@ func FromPackageAttributes(p pkg.Package) []cpe.CPE {
|
||||
return result
|
||||
}
|
||||
|
||||
func candidateTargetSw(p pkg.Package) []string {
|
||||
if p.Type == pkg.WordpressPluginPkg {
|
||||
return []string{"wordpress"}
|
||||
}
|
||||
return []string{cpe.Any}
|
||||
}
|
||||
|
||||
//nolint:funlen
|
||||
func candidateVendors(p pkg.Package) []string {
|
||||
// in ecosystems where the packaging metadata does not have a clear field to indicate a vendor (or a field that
|
||||
|
||||
@ -719,6 +719,31 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:ruby_rake:ruby_rake:2.7.6-r0:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "wordpress plugin",
|
||||
p: pkg.Package{
|
||||
Name: "WP Coder",
|
||||
Version: "2.5.1",
|
||||
Type: pkg.WordpressPluginPkg,
|
||||
Metadata: pkg.WordpressPluginEntry{
|
||||
PluginInstallDirectory: "wp-coder",
|
||||
Author: "Wow-Company",
|
||||
AuthorURI: "https://wow-estore.com",
|
||||
},
|
||||
},
|
||||
expected: []string{
|
||||
"cpe:2.3:a:wow-company:wp-coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow-company:wp_coder:2.5.1:*:*:*:*:wordpress:*:*", // this is the correct CPE relative to CVE-2021-25053
|
||||
"cpe:2.3:a:wow-estore:wp-coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow-estore:wp_coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow:wp-coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow:wp_coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow_company:wp-coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow_company:wp_coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow_estore:wp-coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wow_estore:wp_coder:2.5.1:*:*:*:*:wordpress:*:*",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@ -21,12 +21,18 @@ func candidateVendorsForWordpressPlugin(p pkg.Package) fieldCandidateSet {
|
||||
|
||||
vendors := newFieldCandidateSet()
|
||||
|
||||
if metadata.Author != "" {
|
||||
vendors.addValue(strings.ToLower(metadata.Author))
|
||||
}
|
||||
|
||||
if metadata.AuthorURI != "" {
|
||||
matchMap := internal.MatchNamedCaptureGroups(vendorFromURLRegexp, metadata.AuthorURI)
|
||||
if vendor, ok := matchMap["vendor"]; ok && vendor != "" {
|
||||
vendors.addValue(vendor)
|
||||
vendors.addValue(strings.ToLower(vendor))
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if len(vendors) == 0 {
|
||||
// add plugin_name + _project as a vendor if no Author URI found
|
||||
vendors.addValue(fmt.Sprintf("%s_project", normalizeWordpressPluginName(p.Name)))
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ func Test_candidateVendorsForWordpressPlugin(t *testing.T) {
|
||||
AuthorURI: "https://automattic.com/wordpress-plugins/",
|
||||
},
|
||||
},
|
||||
expected: []string{"automattic"},
|
||||
expected: []string{"automattic - anti-spam team", "automattic"},
|
||||
},
|
||||
{
|
||||
name: "All-in-One WP Migration",
|
||||
@ -47,7 +47,7 @@ func Test_candidateVendorsForWordpressPlugin(t *testing.T) {
|
||||
AuthorURI: "https://bookingultrapro.com/",
|
||||
},
|
||||
},
|
||||
expected: []string{"bookingultrapro"},
|
||||
expected: []string{"booking ultra pro", "bookingultrapro"},
|
||||
},
|
||||
{
|
||||
name: "Coming Soon Chop Chop",
|
||||
@ -58,7 +58,7 @@ func Test_candidateVendorsForWordpressPlugin(t *testing.T) {
|
||||
AuthorURI: "https://www.chop-chop.org",
|
||||
},
|
||||
},
|
||||
expected: []string{"chop-chop"},
|
||||
expected: []string{"chop-chop.org", "chop-chop"},
|
||||
},
|
||||
{
|
||||
name: "Access Code Feeder",
|
||||
@ -71,6 +71,22 @@ func Test_candidateVendorsForWordpressPlugin(t *testing.T) {
|
||||
// When a plugin as no `Author URI` use plugin_name + _project as a vendor
|
||||
expected: []string{"access_code_feeder_project"},
|
||||
},
|
||||
{
|
||||
name: "WP Coder",
|
||||
pkg: pkg.Package{
|
||||
Name: "WP Coder",
|
||||
Metadata: pkg.WordpressPluginEntry{
|
||||
PluginInstallDirectory: "wp-coder",
|
||||
Author: "Wow-Company",
|
||||
AuthorURI: "https://wow-estore.com/",
|
||||
},
|
||||
},
|
||||
// found in the wild https://plugins.trac.wordpress.org/browser/wp-coder/tags/2.5.1/wp-coder.php
|
||||
expected: []string{
|
||||
"wow-company", // this is the correct answer relative to CPEs registered on CVE-2021-25053
|
||||
"wow-estore",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user