Projects STRLCPY grype Commits 6a46070c
🤬
  • fix: correct APK CPE version comparison logic (#1165)

    Previously, the -r{buildindex} suffix of APK package versions were
    treated as pre-release versions per the fuzzy matcher logic; however,
    these should be treated as equivalent to the release version for the
    purposes of collecting CPE-based matches for APK packages.
    
    We may want to make a similar change in syft to generate cleaner CPE
    versions for APK packages, but making the change in grype corrects
    behaviour for previously-generated SBOMs as well.
    
    Signed-off-by: Weston Steimel <[email protected]>
  • Loading...
  • Weston Steimel committed with GitHub 1 year ago
    6a46070c
    1 parent 57543603
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    grype/matcher/apk/matcher_test.go
    skipped 367 lines
    368 368   assertMatches(t, expected, actual)
    369 369  }
    370 370   
     371 +func TestNvdMatchesProperVersionFiltering(t *testing.T) {
     372 + nvdVulnMatch := grypeDB.Vulnerability{
     373 + ID: "CVE-2020-1",
     374 + VersionConstraint: "<= 0.9.11",
     375 + VersionFormat: "unknown",
     376 + CPEs: []string{`cpe:2.3:a:lib_vnc_project-\(server\):libvncserver:*:*:*:*:*:*:*:*`},
     377 + Namespace: "nvd:cpe",
     378 + }
     379 + nvdVulnNoMatch := grypeDB.Vulnerability{
     380 + ID: "CVE-2020-2",
     381 + VersionConstraint: "< 0.9.11",
     382 + VersionFormat: "unknown",
     383 + CPEs: []string{`cpe:2.3:a:lib_vnc_project-\(server\):libvncserver:*:*:*:*:*:*:*:*`},
     384 + Namespace: "nvd:cpe",
     385 + }
     386 + store := mockStore{
     387 + backend: map[string]map[string][]grypeDB.Vulnerability{
     388 + "nvd:cpe": {
     389 + "libvncserver": []grypeDB.Vulnerability{nvdVulnMatch, nvdVulnNoMatch},
     390 + },
     391 + },
     392 + }
     393 + 
     394 + provider, err := db.NewVulnerabilityProvider(&store)
     395 + require.NoError(t, err)
     396 + 
     397 + m := Matcher{}
     398 + d, err := distro.New(distro.Alpine, "3.12.0", "")
     399 + if err != nil {
     400 + t.Fatalf("failed to create a new distro: %+v", err)
     401 + }
     402 + p := pkg.Package{
     403 + ID: pkg.ID(uuid.NewString()),
     404 + Name: "libvncserver",
     405 + Version: "0.9.11-r10",
     406 + Type: syftPkg.ApkPkg,
     407 + CPEs: []cpe.CPE{
     408 + cpe.Must("cpe:2.3:a:*:libvncserver:0.9.11:*:*:*:*:*:*:*"),
     409 + },
     410 + }
     411 + 
     412 + vulnFound, err := vulnerability.NewVulnerability(nvdVulnMatch)
     413 + assert.NoError(t, err)
     414 + vulnFound.CPEs = []cpe.CPE{cpe.Must(nvdVulnMatch.CPEs[0])}
     415 + 
     416 + expected := []match.Match{
     417 + {
     418 + 
     419 + Vulnerability: *vulnFound,
     420 + Package: p,
     421 + Details: []match.Detail{
     422 + {
     423 + Type: match.CPEMatch,
     424 + Confidence: 0.9,
     425 + SearchedBy: search.CPEParameters{
     426 + CPEs: []string{"cpe:2.3:a:*:libvncserver:0.9.11:*:*:*:*:*:*:*"},
     427 + Namespace: "nvd:cpe",
     428 + },
     429 + Found: search.CPEResult{
     430 + CPEs: []string{vulnFound.CPEs[0].BindToFmtString()},
     431 + VersionConstraint: vulnFound.Constraint.String(),
     432 + VulnerabilityID: "CVE-2020-1",
     433 + },
     434 + Matcher: match.ApkMatcher,
     435 + },
     436 + },
     437 + },
     438 + }
     439 + 
     440 + actual, err := m.Match(provider, d, p)
     441 + assert.NoError(t, err)
     442 + 
     443 + assertMatches(t, expected, actual)
     444 +}
     445 + 
    371 446  func TestNvdMatchesWithSecDBFix(t *testing.T) {
    372 447   nvdVuln := grypeDB.Vulnerability{
    373 448   ID: "CVE-2020-1",
    skipped 263 lines
  • ■ ■ ■ ■ ■ ■
    grype/search/cpe.go
    skipped 2 lines
    3 3  import (
    4 4   "fmt"
    5 5   "sort"
     6 + "strings"
    6 7   
    7 8   "github.com/facebookincubator/nvdtools/wfn"
    8 9   "github.com/scylladb/go-set/strset"
    skipped 3 lines
    12 13   "github.com/anchore/grype/grype/version"
    13 14   "github.com/anchore/grype/grype/vulnerability"
    14 15   "github.com/anchore/syft/syft/cpe"
     16 + syftPkg "github.com/anchore/syft/syft/pkg"
    15 17  )
    16 18   
    17 19  type CPEParameters struct {
    skipped 38 lines
    56 58   return true
    57 59  }
    58 60   
     61 +func alpineCPEComparableVersion(version string) string {
     62 + // clean the alpine package version so that it compares correctly with the CPE version comparison logic
     63 + // alpine versions are suffixed with -r{buildindex}; however, if left intact CPE comparison logic will
     64 + // incorrectly treat these as a pre-release. In actuality, we just want to treat 1.2.3-r21 as equivalent to
     65 + // 1.2.3 for purposes of CPE-based matching since the alpine fix should filter out any cases where a later
     66 + // build fixes something that was vulnerable in 1.2.3
     67 + components := strings.Split(version, "-r")
     68 + cpeComparableVersion := version
     69 + 
     70 + if len(components) == 2 {
     71 + cpeComparableVersion = components[0]
     72 + }
     73 + 
     74 + return cpeComparableVersion
     75 +}
     76 + 
    59 77  // ByPackageCPE retrieves all vulnerabilities that match the generated CPE
    60 78  func ByPackageCPE(store vulnerability.ProviderByCPE, p pkg.Package, upstreamMatcher match.MatcherType) ([]match.Match, error) {
    61 79   // we attempt to merge match details within the same matcher when searching by CPEs, in this way there are fewer duplicated match
    skipped 2 lines
    64 82   for _, c := range p.CPEs {
    65 83   // prefer the CPE version, but if npt specified use the package version
    66 84   searchVersion := c.Version
     85 + 
     86 + if p.Type == syftPkg.ApkPkg {
     87 + searchVersion = alpineCPEComparableVersion(searchVersion)
     88 + }
     89 + 
    67 90   if searchVersion == wfn.NA || searchVersion == wfn.Any {
    68 91   searchVersion = p.Version
    69 92   }
    skipped 149 lines
  • ■ ■ ■ ■
    test/quality/vulnerability-match-labels
    1  -[email protected]:anchore/vulnerability-match-labels.git:b918f9d3ccb364c80c7b39d05ddc737eae19d6c9
     1 +[email protected]:anchore/vulnerability-match-labels.git:edb7d33af798a9932c4846e24a9e6ac1e7cb43af
Please wait...
Page is in error, reload to recover