mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
Fix: nil memory pointer when scanResults.MetadataProvider is nil
Signed-off-by: Mehdi Moussaif <m.moussaif42@gmail.com>
This commit is contained in:
@@ -44,6 +44,10 @@ func (c RegistryCredentials) IsEmpty() bool {
|
||||
//
|
||||
// Values equal to the threshold are considered failing, too.
|
||||
func ExceedsSeverityThreshold(scanResults *models.PresenterConfig, severity vulnerability.Severity) bool {
|
||||
if scanResults.MetadataProvider == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return grype.HasSeverityAtOrAbove(scanResults.MetadataProvider, severity, scanResults.Matches)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/anchore/grype/grype/db"
|
||||
grypedb "github.com/anchore/grype/grype/db/v5"
|
||||
"github.com/anchore/grype/grype/match"
|
||||
"github.com/anchore/grype/grype/pkg"
|
||||
"github.com/anchore/grype/grype/presenter/models"
|
||||
"github.com/anchore/grype/grype/vulnerability"
|
||||
syftPkg "github.com/anchore/syft/syft/pkg"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -33,49 +39,6 @@ import (
|
||||
// assert.IsType(t, Service{}, svc)
|
||||
// }
|
||||
|
||||
// func TestRegistryCredentials(t *testing.T) {
|
||||
// tt := []struct {
|
||||
// name string
|
||||
// username string
|
||||
// password string
|
||||
// want bool
|
||||
// }{
|
||||
// {
|
||||
// name: "Valid credentials should not be empty",
|
||||
// username: "user",
|
||||
// password: "pass",
|
||||
// want: false,
|
||||
// },
|
||||
// {
|
||||
// name: "Empty username should be considered empty credentials",
|
||||
// username: "",
|
||||
// password: "pass",
|
||||
// want: true,
|
||||
// },
|
||||
// {
|
||||
// name: "Empty password should be considered empty credentials",
|
||||
// username: "user",
|
||||
// password: "",
|
||||
// want: true,
|
||||
// },
|
||||
// {
|
||||
// name: "Empty user and password should be considered empty credentials",
|
||||
// username: "",
|
||||
// password: "",
|
||||
// want: true,
|
||||
// },
|
||||
// }
|
||||
// for _, tc := range tt {
|
||||
// t.Run(tc.name, func(t *testing.T) {
|
||||
// creds := RegistryCredentials{Username: tc.username, Password: tc.password}
|
||||
|
||||
// got := creds.IsEmpty()
|
||||
|
||||
// assert.Equal(t, tc.want, got)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestScan(t *testing.T) {
|
||||
// tt := []struct {
|
||||
// name string
|
||||
@@ -111,124 +74,49 @@ import (
|
||||
// }
|
||||
// }
|
||||
|
||||
// // fakeMetaProvider is a test double that fakes an actual MetadataProvider
|
||||
// type fakeMetaProvider struct {
|
||||
// vulnerabilities map[string]map[string][]grypedb.Vulnerability
|
||||
// metadata map[string]map[string]*grypedb.VulnerabilityMetadata
|
||||
// }
|
||||
// fakeMetaProvider is a test double that fakes an actual MetadataProvider
|
||||
type fakeMetaProvider struct {
|
||||
vulnerabilities map[string]map[string][]grypedb.Vulnerability
|
||||
metadata map[string]map[string]*grypedb.VulnerabilityMetadata
|
||||
}
|
||||
|
||||
// func newFakeMetaProvider() *fakeMetaProvider {
|
||||
// d := fakeMetaProvider{
|
||||
// vulnerabilities: make(map[string]map[string][]grypedb.Vulnerability),
|
||||
// metadata: make(map[string]map[string]*grypedb.VulnerabilityMetadata),
|
||||
// }
|
||||
// d.fillWithData()
|
||||
// return &d
|
||||
// }
|
||||
|
||||
// func (d *fakeMetaProvider) GetAllVulnerabilityMetadata() (*[]grypedb.VulnerabilityMetadata, error) {
|
||||
// return nil, nil
|
||||
// }
|
||||
|
||||
// func (d *fakeMetaProvider) GetVulnerabilityMatchExclusion(id string) ([]grypedb.VulnerabilityMatchExclusion, error) {
|
||||
// return nil, nil
|
||||
// }
|
||||
|
||||
// func (d *fakeMetaProvider) GetVulnerabilityMetadata(id, namespace string) (*grypedb.VulnerabilityMetadata, error) {
|
||||
// return d.metadata[id][namespace], nil
|
||||
// }
|
||||
|
||||
// func (d *fakeMetaProvider) fillWithData() {
|
||||
// d.metadata["CVE-2014-fake-1"] = map[string]*grypedb.VulnerabilityMetadata{
|
||||
// "debian:distro:debian:8": {
|
||||
// ID: "CVE-2014-fake-1",
|
||||
// Namespace: "debian:distro:debian:8",
|
||||
// Severity: "medium",
|
||||
// },
|
||||
// }
|
||||
|
||||
// d.vulnerabilities["debian:distro:debian:8"] = map[string][]grypedb.Vulnerability{
|
||||
// "neutron": {
|
||||
// {
|
||||
// PackageName: "neutron",
|
||||
// Namespace: "debian:distro:debian:8",
|
||||
// VersionConstraint: "< 2014.1.3-6",
|
||||
// ID: "CVE-2014-fake-1",
|
||||
// VersionFormat: "deb",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
|
||||
// func TestExceedsSeverityThreshold(t *testing.T) {
|
||||
// thePkg := pkg.Package{
|
||||
// ID: pkg.ID(uuid.NewString()),
|
||||
// Name: "the-package",
|
||||
// Version: "v0.1",
|
||||
// Type: syftPkg.RpmPkg,
|
||||
// }
|
||||
|
||||
// matches := match.NewMatches()
|
||||
// matches.Add(match.Match{
|
||||
// Vulnerability: vulnerability.Vulnerability{
|
||||
// ID: "CVE-2014-fake-1",
|
||||
// Namespace: "debian:distro:debian:8",
|
||||
// },
|
||||
// Package: thePkg,
|
||||
// Details: match.Details{
|
||||
// {
|
||||
// Type: match.ExactDirectMatch,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
// tt := []struct {
|
||||
// name string
|
||||
// failOnSeverity string
|
||||
// matches match.Matches
|
||||
// expectedResult bool
|
||||
// }{
|
||||
// {
|
||||
// name: "No severity set should pass",
|
||||
// failOnSeverity: "",
|
||||
// matches: matches,
|
||||
// expectedResult: false,
|
||||
// },
|
||||
// {
|
||||
// name: "Fail severity higher than vulnerability should not fail",
|
||||
// failOnSeverity: "high",
|
||||
// matches: matches,
|
||||
// expectedResult: false,
|
||||
// },
|
||||
// {
|
||||
// name: "Fail severity equal to vulnerability should fail",
|
||||
// failOnSeverity: "medium",
|
||||
// matches: matches,
|
||||
// expectedResult: true,
|
||||
// },
|
||||
// {
|
||||
// name: "Fail severity below found vuln should fail",
|
||||
// failOnSeverity: "low",
|
||||
// matches: matches,
|
||||
// expectedResult: true,
|
||||
// },
|
||||
// }
|
||||
|
||||
// metadataProvider := db.NewVulnerabilityMetadataProvider(newFakeMetaProvider())
|
||||
|
||||
// for _, tc := range tt {
|
||||
// t.Run(tc.name, func(t *testing.T) {
|
||||
// scanResults := &models.PresenterConfig{
|
||||
// Matches: tc.matches,
|
||||
// MetadataProvider: metadataProvider,
|
||||
// }
|
||||
// inputSeverity := vulnerability.ParseSeverity(tc.failOnSeverity)
|
||||
// ours := ExceedsSeverityThreshold(scanResults, inputSeverity)
|
||||
|
||||
// assert.Equal(t, tc.expectedResult, ours)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
func newFakeMetaProvider() *fakeMetaProvider {
|
||||
d := fakeMetaProvider{
|
||||
vulnerabilities: make(map[string]map[string][]grypedb.Vulnerability),
|
||||
metadata: make(map[string]map[string]*grypedb.VulnerabilityMetadata),
|
||||
}
|
||||
d.fillWithData()
|
||||
return &d
|
||||
}
|
||||
func (d *fakeMetaProvider) GetAllVulnerabilityMetadata() (*[]grypedb.VulnerabilityMetadata, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (d *fakeMetaProvider) GetVulnerabilityMatchExclusion(id string) ([]grypedb.VulnerabilityMatchExclusion, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (d *fakeMetaProvider) GetVulnerabilityMetadata(id, namespace string) (*grypedb.VulnerabilityMetadata, error) {
|
||||
return d.metadata[id][namespace], nil
|
||||
}
|
||||
func (d *fakeMetaProvider) fillWithData() {
|
||||
d.metadata["CVE-2014-fake-1"] = map[string]*grypedb.VulnerabilityMetadata{
|
||||
"debian:distro:debian:8": {
|
||||
ID: "CVE-2014-fake-1",
|
||||
Namespace: "debian:distro:debian:8",
|
||||
Severity: "medium",
|
||||
},
|
||||
}
|
||||
d.vulnerabilities["debian:distro:debian:8"] = map[string][]grypedb.Vulnerability{
|
||||
"neutron": {
|
||||
{
|
||||
PackageName: "neutron",
|
||||
Namespace: "debian:distro:debian:8",
|
||||
VersionConstraint: "< 2014.1.3-6",
|
||||
ID: "CVE-2014-fake-1",
|
||||
VersionFormat: "deb",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSeverity(t *testing.T) {
|
||||
tests := []struct {
|
||||
@@ -306,6 +194,11 @@ func TestIsEmpty(t *testing.T) {
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Empty struct",
|
||||
creds: RegistryCredentials{},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -372,6 +265,12 @@ func TestValidateDBLoad(t *testing.T) {
|
||||
},
|
||||
expectedErrMessage: "failed to load vulnerability db: Some error",
|
||||
},
|
||||
{
|
||||
name: "load Error, no db status",
|
||||
loadErr: errors.New("Some error"),
|
||||
status: nil,
|
||||
expectedErrMessage: "failed to load vulnerability db: Some error",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -431,3 +330,100 @@ func TestNewScanService(t *testing.T) {
|
||||
svc := NewScanService(defaultConfig)
|
||||
assert.Equal(t, defaultConfig, svc.dbCfg)
|
||||
}
|
||||
|
||||
func TestExceedsSeverityThreshold(t *testing.T) {
|
||||
my_matches := match.NewMatches()
|
||||
my_matches.Add(match.Match{
|
||||
Vulnerability: vulnerability.Vulnerability{
|
||||
ID: "CVE-2014-fake-1",
|
||||
Namespace: "debian:distro:debian:8",
|
||||
},
|
||||
Package: pkg.Package{
|
||||
ID: pkg.ID(uuid.NewString()),
|
||||
Name: "the-package",
|
||||
Version: "v0.1",
|
||||
Type: syftPkg.RpmPkg,
|
||||
},
|
||||
Details: match.Details{
|
||||
{
|
||||
Type: match.ExactDirectMatch,
|
||||
},
|
||||
},
|
||||
})
|
||||
my_metadataProvider := db.NewVulnerabilityMetadataProvider(newFakeMetaProvider())
|
||||
|
||||
type args struct {
|
||||
scanResults *models.PresenterConfig
|
||||
severity vulnerability.Severity
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "No severity set",
|
||||
args: args{
|
||||
scanResults: &models.PresenterConfig{
|
||||
Matches: match.NewMatches(),
|
||||
MetadataProvider: nil,
|
||||
},
|
||||
severity: vulnerability.UnknownSeverity,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "No MetadataProvider",
|
||||
args: args{
|
||||
scanResults: &models.PresenterConfig{
|
||||
Matches: my_matches,
|
||||
MetadataProvider: nil,
|
||||
},
|
||||
severity: vulnerability.MediumSeverity,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Severity higher than vulnerability",
|
||||
args: args{
|
||||
scanResults: &models.PresenterConfig{
|
||||
Matches: my_matches,
|
||||
MetadataProvider: my_metadataProvider,
|
||||
},
|
||||
severity: vulnerability.HighSeverity,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "Severity equal to vulnerability",
|
||||
args: args{
|
||||
scanResults: &models.PresenterConfig{
|
||||
Matches: my_matches,
|
||||
MetadataProvider: my_metadataProvider,
|
||||
},
|
||||
severity: vulnerability.MediumSeverity,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "Fail severity below found vulnerability",
|
||||
args: args{
|
||||
scanResults: &models.PresenterConfig{
|
||||
Matches: my_matches,
|
||||
MetadataProvider: my_metadataProvider,
|
||||
},
|
||||
severity: vulnerability.LowSeverity,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
got := ExceedsSeverityThreshold(tt.args.scanResults, tt.args.severity)
|
||||
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user