Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add config for inferring fixes from NVD #411

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions cmd/grype-db/cli/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,12 @@ func runBuild(cfg buildConfig) error {
}

return process.Build(process.BuildConfig{
SchemaVersion: cfg.SchemaVersion,
Directory: cfg.Directory,
States: states,
Timestamp: earliestTimestamp(states),
IncludeCPEParts: cfg.IncludeCPEParts,
SchemaVersion: cfg.SchemaVersion,
Directory: cfg.Directory,
States: states,
Timestamp: earliestTimestamp(states),
IncludeCPEParts: cfg.IncludeCPEParts,
InferNVDFixVersions: cfg.InferNVDFixVersions,
})
}

Expand Down
13 changes: 8 additions & 5 deletions cmd/grype-db/cli/options/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ type Build struct {
SchemaVersion int `yaml:"schema-version" json:"schema-version" mapstructure:"schema-version"`

// unbound options
IncludeCPEParts []string `yaml:"include-cpe-parts" json:"include-cpe-parts" mapstructure:"include-cpe-parts"`
IncludeCPEParts []string `yaml:"include-cpe-parts" json:"include-cpe-parts" mapstructure:"include-cpe-parts"`
InferNVDFixVersions bool `yaml:"infer-nvd-fix-versions" json:"infer-nvd-fix-versions" mapstructure:"infer-nvd-fix-versions"`
}

func DefaultBuild() Build {
return Build{
DBLocation: DefaultDBLocation(),
SkipValidation: false,
SchemaVersion: process.DefaultSchemaVersion,
IncludeCPEParts: []string{"a"},
DBLocation: DefaultDBLocation(),
SkipValidation: false,
SchemaVersion: process.DefaultSchemaVersion,
IncludeCPEParts: []string{"a"},
InferNVDFixVersions: true,
}
}

Expand Down Expand Up @@ -56,6 +58,7 @@ func (o *Build) BindFlags(flags *pflag.FlagSet, v *viper.Viper) error {

// set default values for non-bound struct items
v.SetDefault("build.include-cpe-parts", o.IncludeCPEParts)
v.SetDefault("build.infer-nvd-fix-versions", o.InferNVDFixVersions)

return o.DBLocation.BindFlags(flags, v)
}
13 changes: 7 additions & 6 deletions pkg/process/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ import (
)

type BuildConfig struct {
SchemaVersion int
Directory string
States provider.States
Timestamp time.Time
IncludeCPEParts []string
SchemaVersion int
Directory string
States provider.States
Timestamp time.Time
IncludeCPEParts []string
InferNVDFixVersions bool
}

func Build(cfg BuildConfig) error {
Expand Down Expand Up @@ -101,7 +102,7 @@ func getProcessors(cfg BuildConfig) ([]data.Processor, error) {
case grypeDBv4.SchemaVersion:
return v4.Processors(), nil
case grypeDBv5.SchemaVersion:
return v5.Processors(v5.NewConfig(v5.WithCPEParts(cfg.IncludeCPEParts))), nil
return v5.Processors(v5.NewConfig(v5.WithCPEParts(cfg.IncludeCPEParts), v5.WithInferNVDFixVersions(cfg.InferNVDFixVersions))), nil
default:
return nil, fmt.Errorf("unable to create processor: unsupported schema version: %+v", cfg.SchemaVersion)
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/process/v5/processors.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ func WithCPEParts(included []string) Option {
}
}

func WithInferNVDFixVersions(infer bool) Option {
return func(cfg *Config) {
cfg.NVD.InferNVDFixVersions = infer
}
}

func NewConfig(options ...Option) Config {
var cfg Config
for _, option := range options {
Expand Down
16 changes: 12 additions & 4 deletions pkg/process/v5/transformers/nvd/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import (
)

type Config struct {
CPEParts *strset.Set
CPEParts *strset.Set
InferNVDFixVersions bool
}

func defaultConfig() Config {
return Config{
CPEParts: strset.New("a"),
CPEParts: strset.New("a"),
InferNVDFixVersions: true,
}
}

Expand Down Expand Up @@ -91,7 +93,7 @@ func transform(cfg Config, vulnerability unmarshal.NVDVulnerability) ([]data.Ent
PackageName: grypeNamespace.Resolver().Normalize(p.Product),
Namespace: entryNamespace,
CPEs: orderedCPEs,
Fix: getFix(matches),
Fix: getFix(matches, cfg.InferNVDFixVersions),
})
}

Expand Down Expand Up @@ -127,7 +129,13 @@ func getVersionFormat(name string, cpes []string) version.Format {
return version.UnknownFormat
}

func getFix(matches []nvd.CpeMatch) grypeDB.Fix {
func getFix(matches []nvd.CpeMatch, inferNVDFixVersions bool) grypeDB.Fix {
if !inferNVDFixVersions {
return grypeDB.Fix{
State: grypeDB.UnknownFixState,
}
}

possiblyFixed := strset.New()
knownAffected := strset.New()
unspecifiedSet := strset.New("*", "-", "*")
Expand Down
10 changes: 9 additions & 1 deletion pkg/process/v5/transformers/nvd/transform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1061,8 +1061,16 @@ func TestGetFix(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fix := getFix(tt.matches)
fix := getFix(tt.matches, true)
assert.Equal(t, tt.expected, fix)
})

t.Run(tt.name+" don't infer NVD fixes", func(t *testing.T) {
fix := getFix(tt.matches, false)
assert.Equal(t, grypeDB.Fix{
Versions: nil,
State: "unknown",
}, fix)
})
}
}
Loading