Skip to content

Commit

Permalink
fix: improve Jenkins plugin known CPE index construction
Browse files Browse the repository at this point in the history
Improves the logic for adding known CPEs for Jenkins plugins and
prefers non-deprecated CPEs

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
  • Loading branch information
westonsteimel committed Apr 23, 2024
1 parent 21f62aa commit b899af8
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 47 deletions.
265 changes: 242 additions & 23 deletions syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,14 @@ func filterCpeList(cpeList CpeList) CpeList {
normalizedName := normalizeCPE(parsedName).BindToURI()
cpeItem.Name = normalizedName

parsedCPE, err := wfn.Parse(cpeItem.Cpe23Item.Name)
cpeName := cpeItem.Cpe23Item.Name
if cpeItem.Cpe23Item.Deprecation.DeprecatedBy.Name != "" {
cpeName = cpeItem.Cpe23Item.Deprecation.DeprecatedBy.Name
}

parsedCPE, err := wfn.Parse(cpeName)
if err != nil {
log.Printf("unable to parse CPE value %q: %s", cpeItem.Cpe23Item.Name, err)
log.Printf("unable to parse CPE value %q: %s", cpeName, err)
continue
}

Expand All @@ -97,18 +102,19 @@ func normalizeCPE(cpe *wfn.Attributes) *wfn.Attributes {
}

const (
prefixForNPMPackages = "https://www.npmjs.com/package/"
prefixForRubyGems = "https://rubygems.org/gems/"
prefixForRubyGemsHTTP = "http://rubygems.org/gems/"
prefixForNativeRubyGems = "https://github.com/ruby/"
prefixForPyPIPackages = "https://pypi.org/project/"
prefixForJenkinsPlugins = "https://github.com/jenkinsci/"
prefixForRustCrates = "https://crates.io/crates/"
prefixForPHPPear = "https://pear.php.net/"
prefixForPHPPearHTTP = "http://pear.php.net/"
prefixForPHPPecl = "https://pecl.php.net/"
prefixForPHPPeclHTTP = "http://pecl.php.net/"
prefixForPHPComposer = "https://packagist.org/packages/"
prefixForNPMPackages = "https://www.npmjs.com/package/"
prefixForRubyGems = "https://rubygems.org/gems/"
prefixForRubyGemsHTTP = "http://rubygems.org/gems/"
prefixForNativeRubyGems = "https://github.com/ruby/"
prefixForPyPIPackages = "https://pypi.org/project/"
prefixForJenkinsPlugins = "https://plugins.jenkins.io/"
prefixForJenkinsPluginsGitHub = "https://github.com/jenkinsci/"
prefixForRustCrates = "https://crates.io/crates/"
prefixForPHPPear = "https://pear.php.net/"
prefixForPHPPearHTTP = "http://pear.php.net/"
prefixForPHPPecl = "https://pecl.php.net/"
prefixForPHPPeclHTTP = "http://pecl.php.net/"
prefixForPHPComposer = "https://packagist.org/packages/"
)

// indexCPEList creates an index of CPEs by ecosystem.
Expand Down Expand Up @@ -136,8 +142,11 @@ func indexCPEList(list CpeList) *dictionary.Indexed {
case strings.HasPrefix(ref, prefixForPyPIPackages):
addEntryForPyPIPackage(indexed, ref, cpeItemName)

case strings.HasPrefix(ref, prefixForJenkinsPlugins):
case strings.HasPrefix(ref, prefixForJenkinsPluginsGitHub):
// It _might_ be a jenkins plugin!
addEntryForJenkinsPluginGitHub(indexed, ref, cpeItemName)

case strings.HasPrefix(ref, prefixForJenkinsPlugins):
addEntryForJenkinsPlugin(indexed, ref, cpeItemName)

case strings.HasPrefix(ref, prefixForRustCrates):
Expand Down Expand Up @@ -170,9 +179,9 @@ func addEntryForRustCrate(indexed *dictionary.Indexed, ref string, cpeItemName s
indexed.EcosystemPackages[dictionary.EcosystemRustCrates][ref] = cpeItemName
}

func addEntryForJenkinsPlugin(indexed *dictionary.Indexed, ref string, cpeItemName string) {
func addEntryForJenkinsPluginGitHub(indexed *dictionary.Indexed, ref string, cpeItemName string) {
// Prune off the non-package-name parts of the URL
ref = strings.TrimPrefix(ref, prefixForJenkinsPlugins)
ref = strings.TrimPrefix(ref, prefixForJenkinsPluginsGitHub)
ref = strings.Split(ref, "/")[0]

if !strings.HasSuffix(ref, "-plugin") {
Expand All @@ -189,6 +198,22 @@ func addEntryForJenkinsPlugin(indexed *dictionary.Indexed, ref string, cpeItemNa
indexed.EcosystemPackages[dictionary.EcosystemJenkinsPlugins][ref] = cpeItemName
}

func addEntryForJenkinsPlugin(indexed *dictionary.Indexed, ref string, cpeItemName string) {
// Prune off the non-package-name parts of the URL
ref = strings.TrimPrefix(ref, prefixForJenkinsPlugins)
ref = strings.Split(ref, "/")[0]

if ref == "" {
return
}

if _, ok := indexed.EcosystemPackages[dictionary.EcosystemJenkinsPlugins]; !ok {
indexed.EcosystemPackages[dictionary.EcosystemJenkinsPlugins] = make(dictionary.Packages)
}

indexed.EcosystemPackages[dictionary.EcosystemJenkinsPlugins][ref] = cpeItemName
}

func addEntryForPyPIPackage(indexed *dictionary.Indexed, ref string, cpeItemName string) {
// Prune off the non-package-name parts of the URL
ref = strings.TrimPrefix(ref, prefixForPyPIPackages)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ func Test_addEntryFuncs(t *testing.T) {
},
},
{
name: "addEntryForJenkinsPlugin",
addEntryFunc: addEntryForJenkinsPlugin,
name: "addEntryForJenkinsPluginGitHub",
addEntryFunc: addEntryForJenkinsPluginGitHub,
inputRef: "https://github.com/jenkinsci/sonarqube-plugin",
inputCpeItemName: "cpe:2.3:a:sonarsource:sonarqube_scanner:2.7:*:*:*:*:jenkins:*:*",
expectedIndexed: dictionary.Indexed{
Expand All @@ -78,14 +78,27 @@ func Test_addEntryFuncs(t *testing.T) {
},
},
{
name: "addEntryForJenkinsPlugin: not actually a plugin",
addEntryFunc: addEntryForJenkinsPlugin,
name: "addEntryForJenkinsPluginGitHub: not actually a plugin",
addEntryFunc: addEntryForJenkinsPluginGitHub,
inputRef: "https://github.com/jenkinsci/jenkins",
inputCpeItemName: "cpe:2.3:a:jenkins:jenkinsci:2.7:*:*:*:*:*:*:*",
expectedIndexed: dictionary.Indexed{
EcosystemPackages: map[string]dictionary.Packages{},
},
},
{
name: "addEntryForJenkinsPlugin",
addEntryFunc: addEntryForJenkinsPlugin,
inputRef: "https://plugins.jenkins.io/svn-partial-release-mgr/release",
inputCpeItemName: "cpe:2.3:a:jenkins:subversion_partial_release_manager:1.0.1:*:*:*:*:jenkins:*:*",
expectedIndexed: dictionary.Indexed{
EcosystemPackages: map[string]dictionary.Packages{
dictionary.EcosystemJenkinsPlugins: {
"svn-partial-release-mgr": "cpe:2.3:a:jenkins:subversion_partial_release_manager:1.0.1:*:*:*:*:jenkins:*:*",
},
},
},
},
{
name: "addEntryForPyPIPackage",
addEntryFunc: addEntryForPyPIPackage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ type CpeItem struct {
} `xml:"reference"`
} `xml:"references"`
Cpe23Item struct {
Name string `xml:"name,attr"`
Name string `xml:"name,attr"`
Deprecation struct {
DeprecatedBy struct {
Name string `xml:"name,attr"`
} `xml:"deprecated-by"`
} `xml:"deprecation"`
} `xml:"cpe23-item"`
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"ecosystems": {
"jenkins_plugins": {
"sonarqube": "cpe:2.3:a:sonarsource:sonarqube_scanner:*:*:*:*:*:jenkins:*:*"
"fireline": "cpe:2.3:a:jenkins:360_fireline:*:*:*:*:*:jenkins:*:*",
"sonarqube": "cpe:2.3:a:sonarsource:sonarqube_scanner:*:*:*:*:*:jenkins:*:*",
"svn-partial-release-mgr": "cpe:2.3:a:jenkins:subversion_partial_release_manager:*:*:*:*:*:jenkins:*:*"
},
"npm": {
"merge-recursive": "cpe:2.3:a:umbraengineering:merge-recursive:*:*:*:*:*:node.js:*:*",
Expand Down Expand Up @@ -30,7 +32,7 @@
"xhprof": "cpe:2.3:a:php:xhprof:*:*:*:*:*:*:*:*"
},
"pypi": {
"vault-cli": "cpe:2.3:a:ukg:vault-cli:*:*:*:*:*:python:*:*"
"vault-cli": "cpe:2.3:a:vault-cli_project:vault-cli:*:*:*:*:*:python:*:*"
},
"rubygems": {
"openssl": "cpe:2.3:a:ruby-lang:openssl:*:*:*:*:*:*:*:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24994,4 +24994,26 @@
</references>
<cpe-23:cpe23-item name="cpe:2.3:a:frappant:forms_export:-:*:*:*:*:typo3:*:*"/>
</cpe-item>
<cpe-item name="cpe:/a:jenkins:_subversion_partial_release_manager:1.0.1::~~~jenkins~~" deprecated="true" deprecation_date="2020-06-04T11:50:37.430Z">
<title xml:lang="en-US">Jenkins Subversion Partial Release Manager 1.0.1 for Jenkins</title>
<references>
<reference href="https://github.com/jenkinsci/svn-partial-release-mgr-plugin">Version</reference>
<reference href="https://plugins.jenkins.io/svn-partial-release-mgr">Product</reference>
</references>
<cpe-23:cpe23-item name="cpe:2.3:a:jenkins:_subversion_partial_release_manager:1.0.1:*:*:*:*:jenkins:*:*">
<cpe-23:deprecation date="2020-06-04T07:50:37.430-04:00">
<cpe-23:deprecated-by name="cpe:2.3:a:jenkins:subversion_partial_release_manager:1.0.1:*:*:*:*:jenkins:*:*" type="NAME_CORRECTION"/>
</cpe-23:deprecation>
</cpe-23:cpe23-item>
</cpe-item>
<cpe-item name="cpe:/a:jenkins:360_fireline:1.0::~~~jenkins~~">
<title xml:lang="en-US">Jenkins 360 FireLine 1.0 for Jenkins</title>
<references>
<reference href="https://plugins.jenkins.io/fireline">Product</reference>
<reference href="https://github.com/jenkinsci/fireline-plugin">Version</reference>
</references>
<cpe-23:cpe23-item name="cpe:2.3:a:jenkins:360_fireline:1.0:*:*:*:*:jenkins:*:*"/>
</cpe-item>
</cpe-list>
</cpe-list>
</cpe-list>

0 comments on commit b899af8

Please sign in to comment.