Skip to content

Commit

Permalink
fix: add nvd fix version when versionEndExcluding provided (#112)
Browse files Browse the repository at this point in the history
* fix: add nvd fix version when versionEndExcluding provided

Signed-off-by: James Neate <[email protected]>

* deduplicate NVD fix versions

Signed-off-by: Weston Steimel <[email protected]>

* tests for NVD getFix

Signed-off-by: Weston Steimel <[email protected]>

* lint fix

Signed-off-by: Weston Steimel <[email protected]>

* handle more complex cases

Signed-off-by: Weston Steimel <[email protected]>

---------

Signed-off-by: James Neate <[email protected]>
Signed-off-by: Weston Steimel <[email protected]>
Co-authored-by: Weston Steimel <[email protected]>
  • Loading branch information
jneate and westonsteimel authored Oct 15, 2024
1 parent bf0e5b0 commit e47abb8
Show file tree
Hide file tree
Showing 6 changed files with 332 additions and 15 deletions.
2 changes: 1 addition & 1 deletion pkg/process/v1/transformers/nvd/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func Transform(vulnerability unmarshal.NVDVulnerability) ([]data.Entry, error) {
vuln := grypeDB.Vulnerability{
ID: vulnerability.ID,
RecordSource: recordSource,
VersionConstraint: buildConstraints(uniquePkgs.Matches(p)),
VersionConstraint: buildConstraints(matches),
VersionFormat: "unknown", // TODO: derive this from the target software
PackageName: p.Product,
Namespace: "nvd", // should the vendor be here? or in other metadata?
Expand Down
2 changes: 1 addition & 1 deletion pkg/process/v2/transformers/nvd/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func Transform(vulnerability unmarshal.NVDVulnerability) ([]data.Entry, error) {
vuln := grypeDB.Vulnerability{
ID: vulnerability.ID,
RecordSource: recordSource,
VersionConstraint: buildConstraints(uniquePkgs.Matches(p)),
VersionConstraint: buildConstraints(matches),
VersionFormat: "unknown", // TODO: derive this from the target software
PackageName: p.Product,
Namespace: "nvd", // should the vendor be here? or in other metadata?
Expand Down
2 changes: 1 addition & 1 deletion pkg/process/v3/transformers/nvd/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func Transform(vulnerability unmarshal.NVDVulnerability) ([]data.Entry, error) {
// create vulnerability entry
allVulns = append(allVulns, grypeDB.Vulnerability{
ID: vulnerability.ID,
VersionConstraint: buildConstraints(uniquePkgs.Matches(p)),
VersionConstraint: buildConstraints(matches),
VersionFormat: "unknown",
PackageName: p.Product,
Namespace: entryNamespace,
Expand Down
2 changes: 1 addition & 1 deletion pkg/process/v4/transformers/nvd/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func Transform(vulnerability unmarshal.NVDVulnerability) ([]data.Entry, error) {
// create vulnerability entry
allVulns = append(allVulns, grypeDB.Vulnerability{
ID: vulnerability.ID,
VersionConstraint: buildConstraints(uniquePkgs.Matches(p)),
VersionConstraint: buildConstraints(matches),
VersionFormat: "unknown",
PackageName: grypeNamespace.Resolver().Normalize(p.Product),
Namespace: entryNamespace,
Expand Down
57 changes: 53 additions & 4 deletions pkg/process/v5/transformers/nvd/transform.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package nvd

import (
"slices"
"sort"
"strings"

"github.com/scylladb/go-set/strset"

"github.com/anchore/grype-db/internal"
"github.com/anchore/grype-db/pkg/data"
"github.com/anchore/grype-db/pkg/process/v5/transformers"
Expand Down Expand Up @@ -64,14 +67,12 @@ func Transform(vulnerability unmarshal.NVDVulnerability) ([]data.Entry, error) {
allVulns = append(allVulns, grypeDB.Vulnerability{
ID: vulnerability.ID,
PackageQualifiers: qualifiers,
VersionConstraint: buildConstraints(uniquePkgs.Matches(p)),
VersionConstraint: buildConstraints(matches),
VersionFormat: strings.ToLower(getVersionFormat(p.Product, orderedCPEs).String()),
PackageName: grypeNamespace.Resolver().Normalize(p.Product),
Namespace: entryNamespace,
CPEs: orderedCPEs,
Fix: grypeDB.Fix{
State: grypeDB.UnknownFixState,
},
Fix: getFix(matches),
})
}

Expand Down Expand Up @@ -107,6 +108,54 @@ func getVersionFormat(name string, cpes []string) version.Format {
return version.UnknownFormat
}

func getFix(matches []nvd.CpeMatch) grypeDB.Fix {
possiblyFixed := strset.New()
knownAffected := strset.New()
unspecifiedSet := strset.New("*", "-", "*")

for _, match := range matches {
if !match.Vulnerable {
continue
}

if match.VersionEndExcluding != nil && !unspecifiedSet.Has(*match.VersionEndExcluding) {
possiblyFixed.Add(*match.VersionEndExcluding)
}

if match.VersionStartIncluding != nil && !unspecifiedSet.Has(*match.VersionStartIncluding) {
knownAffected.Add(*match.VersionStartIncluding)
}

if match.VersionEndIncluding != nil && !unspecifiedSet.Has(*match.VersionEndIncluding) {
knownAffected.Add(*match.VersionEndIncluding)
}

matchCPE, err := cpe.New(match.Criteria, cpe.DeclaredSource)
if err != nil {
continue
}

if !unspecifiedSet.Has(matchCPE.Attributes.Version) {
knownAffected.Add(matchCPE.Attributes.Version)
}
}

possiblyFixed.Remove(knownAffected.List()...)

var fixes []string
fixState := grypeDB.UnknownFixState
if possiblyFixed.Size() > 0 {
fixState = grypeDB.FixedState
fixes = possiblyFixed.List()
slices.Sort(fixes)
}

return grypeDB.Fix{
Versions: fixes,
State: fixState,
}
}

func getCvss(cvss ...nvd.CvssSummary) []grypeDB.Cvss {
var results []grypeDB.Cvss
for _, c := range cvss {
Expand Down
Loading

0 comments on commit e47abb8

Please sign in to comment.