Ignore explicit list of log4j false positive matches (#559)

This commit is contained in:
Keith Zantow 2021-12-22 13:27:41 -05:00 committed by GitHub
parent 2cc631a25a
commit b618b84bac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 151 additions and 0 deletions

View file

@ -0,0 +1,55 @@
package match
import "github.com/anchore/grype/internal/log"
var explicitIgnoreRules []IgnoreRule
func init() {
type ignoreValues struct {
typ string
vulnerabilities []string
packages []string
}
var explicitIgnores = []ignoreValues{
// Based on https://github.com/anchore/grype/issues/552, which includes a reference to the
// https://github.com/mergebase/log4j-samples collection, we want to filter these explicitly:
{"java-archive",
[]string{"CVE-2021-44228", "CVE-2021-45046", "GHSA-jfh8-c2jp-5v3q", "GHSA-7rjr-3q55-vv33"},
[]string{"log4j-api", "log4j-slf4j-impl", "log4j-to-slf4j", "log4j-1.2-api", "log4j-detector", "log4j-over-slf4j", "slf4j-log4j12"},
},
}
for _, ignore := range explicitIgnores {
for _, vulnerability := range ignore.vulnerabilities {
for _, packageName := range ignore.packages {
explicitIgnoreRules = append(explicitIgnoreRules, IgnoreRule{
Vulnerability: vulnerability,
Package: IgnoreRulePackage{
Name: packageName,
Type: ignore.typ,
},
})
}
}
}
}
// ApplyExplicitIgnoreRules This will filter out matches that are defined above, in the
// explicitIgnores list
func ApplyExplicitIgnoreRules(matches Matches) Matches {
matches, ignored := ApplyIgnoreRules(matches, explicitIgnoreRules)
if len(ignored) > 0 {
log.Debugf("Removed %d explicit vulnerability matches:", len(ignored))
for idx, i := range ignored {
branch := "├──"
if idx == len(ignored)-1 {
branch = "└──"
}
log.Debugf(" %s %s : %s", branch, i.Match.Vulnerability.ID, i.Package.PURL)
}
}
return matches
}

View file

@ -0,0 +1,94 @@
package match
import (
"testing"
"github.com/anchore/grype/grype/pkg"
"github.com/anchore/grype/grype/vulnerability"
syftPkg "github.com/anchore/syft/syft/pkg"
"github.com/stretchr/testify/assert"
)
func Test_ApplyExplicitIgnoreRules(t *testing.T) {
type cvePkg struct {
cve string
pkg string
}
tests := []struct {
name string
typ syftPkg.Type
matches []cvePkg
expected []string
}{
// some explicit log4j-related data:
// "CVE-2021-44228", "CVE-2021-45046", "GHSA-jfh8-c2jp-5v3q", "GHSA-7rjr-3q55-vv33",
// "log4j-api", "log4j-slf4j-impl", "log4j-to-slf4j", "log4j-1.2-api",
{
name: "keeps non-matching packages",
typ: "java-archive",
matches: []cvePkg{
{"CVE-2021-44228", "log4j-core"},
{"CVE-2021-43452", "foo-tool"},
},
expected: []string{"log4j-core", "foo-tool"},
},
{
name: "keeps non-matching CVEs",
typ: "java-archive",
matches: []cvePkg{
{"CVE-2021-428", "log4j-api"},
{"CVE-2021-43452", "foo-tool"},
},
expected: []string{"log4j-api", "foo-tool"},
},
{
name: "filters only matching CVE and package",
typ: "java-archive",
matches: []cvePkg{
{"CVE-2021-44228", "log4j-api"},
{"CVE-2021-44228", "log4j-core"},
},
expected: []string{"log4j-core"},
},
{
name: "filters all matching CVEs and packages",
typ: "java-archive",
matches: []cvePkg{
{"GHSA-jfh8-c2jp-5v3q", "log4j-api"},
{"GHSA-jfh8-c2jp-5v3q", "log4j-slf4j-impl"},
},
expected: []string{},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
matches := Matches{
byPackage: make(map[pkg.ID][]Match),
}
for _, cp := range test.matches {
matches.byPackage[pkg.ID(cp.pkg)] = []Match{
{
Package: pkg.Package{
Name: cp.pkg,
Type: test.typ,
},
Vulnerability: vulnerability.Vulnerability{
ID: cp.cve,
},
},
}
}
filtered := ApplyExplicitIgnoreRules(matches)
var found []string
for match := range filtered.Enumerate() {
found = append(found, match.Package.Name)
}
assert.ElementsMatch(t, test.expected, found)
})
}
}

View file

@ -108,6 +108,8 @@ func (c *controller) findMatches(provider vulnerability.Provider, d *distro.Dist
packagesProcessed.SetCompleted()
vulnerabilitiesDiscovered.SetCompleted()
res = match.ApplyExplicitIgnoreRules(res)
return res
}