fix app vuln false positives (#19905)

This commit is contained in:
Tim Lee 2024-06-21 08:05:18 -06:00 committed by GitHub
parent 0dd620e61b
commit cb5fb65c5e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 57 additions and 25 deletions

View file

@ -209,6 +209,15 @@ func GetKnownNVDBugRules() (CPEMatchingRules, error) {
return cpeMeta.Product == "visual_studio_code" && cpeMeta.TargetSW == wfn.Any
},
},
// Old macos CPEs without version constraints that should be ignored
CPEMatchingRule{
CVEs: map[string]struct{}{
"CVE-2001-0102": {},
"CVE-1999-0590": {},
"CVE-1999-0524": {},
},
IgnoreAll: true,
},
}
for i, rule := range rules {

View file

@ -312,6 +312,21 @@ func TestTranslateCPEToCVE(t *testing.T) {
},
continuesToUpdate: true,
},
"cpe:2.3:a:apple:safari:17.0:*:*:*:*:macos:*:*": {
includedCVEs: []cve{
{ID: "CVE-2023-42852", resolvedInVersion: "17.1"},
{ID: "CVE-2023-42950", resolvedInVersion: "17.2"},
{ID: "CVE-2024-23273", resolvedInVersion: "17.4"},
},
excludedCVEs: []string{"CVE-2023-28205"},
continuesToUpdate: true,
},
"cpe:2.3:a:apple:safari:16.4.0:*:*:*:*:macos:*:*": {
includedCVEs: []cve{
{ID: "CVE-2023-28205", resolvedInVersion: "16.4.1"},
},
continuesToUpdate: true,
},
}
cveOSTests := []struct {
@ -474,7 +489,9 @@ func TestTranslateCPEToCVE(t *testing.T) {
}
for _, cve := range tc.excludedCVEs {
require.NotContains(t, cvesFound[cpe], cve, tc.cpe)
for _, cveFound := range cvesFound[cpe] {
require.NotEqual(t, cve, cveFound.ID, fmt.Sprintf("%s should not contain %s", cpe, cve))
}
}
}

View file

@ -69,13 +69,42 @@ func (cm *cpeMatch) Match(attrs []*wfn.Attributes, requireVersion bool) (matches
if cm.match(attr, requireVersion) {
matches = append(matches, attr)
}
if osMatch := cm.MatchTargetSW(attr); osMatch != nil {
if osMatch := cm.matchTargetSW(attr); osMatch != nil {
matches = append(matches, osMatch)
}
}
return matches
}
// matchTargetSW returns an OS CPE for the given application CPE
// if the application CPE has a target software attribute and
// matches the given cpeMatch
func (cm *cpeMatch) matchTargetSW(attr *wfn.Attributes) *wfn.Attributes {
if cm == nil || attr == nil {
return nil
}
if attr.Part != "a" || attr.TargetSW == "" {
return nil
}
osAttr := &wfn.Attributes{
Part: "o",
Product: attr.TargetSW,
}
partMatches := cm.Part == osAttr.Part
productMatches := cm.Product == osAttr.Product
versionMatches := cm.Version == wfn.NA || cm.Version == wfn.Any
noVersionRanges := !cm.hasVersionRanges
if partMatches && productMatches && versionMatches && noVersionRanges {
return osAttr
}
return nil
}
// Match implements wfn.Matcher interface
func (cm *cpeMatch) match(attr *wfn.Attributes, requireVersion bool) bool {
if cm == nil || cm.Attributes == nil {

View file

@ -51,29 +51,6 @@ func (a *Attributes) MatchWithoutVersion(attr *Attributes) bool {
matchAttr(a.Other, attr.Other)
}
func (a *Attributes) MatchTargetSW(attr *Attributes) *Attributes {
if a == nil || attr == nil {
return nil
}
var osMatch bool
var osAttr *Attributes
if attr.Part == "a" && attr.TargetSW != "" {
osAttr = &Attributes{
Part: "o",
Product: attr.TargetSW,
}
osMatch = matchAttr(a.Part, osAttr.Part) && matchAttr(a.Product, osAttr.Product)
}
if !osMatch {
return nil
}
return osAttr
}
// MatchAll returns a Matcher which matches only if all matchers match
func MatchAll(ms ...Matcher) Matcher {
return &multiMatcher{matchers: ms, allMatch: true}