mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
Added support for severity exceptions in imagescan
This commit add relevant functions to support severity exceptions during image scan. Signed-off-by: VaibhavMalik4187 <vaibhavmalik2018@gmail.com>
This commit is contained in:
committed by
Matthias Bertschy
parent
199c57be30
commit
a31154897f
+24
-14
@@ -60,29 +60,38 @@ func GetImageExceptionsFromFile(filePath string) ([]VulnerabilitiesIgnorePolicy,
|
||||
return policies, nil
|
||||
}
|
||||
|
||||
func getUniqueVulnerabilities(policies []VulnerabilitiesIgnorePolicy) []string {
|
||||
// Create a map to store unique vulnerabilities (case-insensitive)
|
||||
uniqueVulns := make(map[string]bool)
|
||||
func getUniqueVulnerabilitiesAndSeverities(policies []VulnerabilitiesIgnorePolicy) ([]string, []string) {
|
||||
// Create maps with slices as values to store unique vulnerabilities and severities (case-insensitive)
|
||||
uniqueVulns := make(map[string][]string)
|
||||
uniqueSevers := make(map[string][]string)
|
||||
|
||||
// Iterate over each policy
|
||||
// Iterate over each policy and its vulnerabilities/severities
|
||||
for _, policy := range policies {
|
||||
// Iterate over each vulnerability in the policy
|
||||
for _, vuln := range policy.Vulnerabilities {
|
||||
// Convert to uppercase for case-insensitive comparison
|
||||
vulnLower := strings.ToUpper(vuln)
|
||||
for _, vulnerability := range policy.Vulnerabilities {
|
||||
// Add to slice directly
|
||||
vulnerabilityUppercase := strings.ToUpper(vulnerability)
|
||||
uniqueVulns[vulnerabilityUppercase] = append(uniqueVulns[vulnerabilityUppercase], vulnerability)
|
||||
}
|
||||
|
||||
// Add the vulnerability to the map (only if it's not already present)
|
||||
uniqueVulns[vulnLower] = true
|
||||
for _, severity := range policy.Severities {
|
||||
// Add to slice directly
|
||||
severityUppercase := strings.ToUpper(severity)
|
||||
uniqueSevers[severityUppercase] = append(uniqueSevers[severityUppercase], severity)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the map keys (unique vulnerabilities) to a slice
|
||||
// Extract unique keys (which are unique vulnerabilities/severities) and their slices
|
||||
uniqueVulnsList := make([]string, 0, len(uniqueVulns))
|
||||
for vuln := range uniqueVulns {
|
||||
uniqueVulnsList = append(uniqueVulnsList, vuln)
|
||||
}
|
||||
|
||||
return uniqueVulnsList
|
||||
uniqueSeversList := make([]string, 0, len(uniqueSevers))
|
||||
for sever := range uniqueSevers {
|
||||
uniqueSeversList = append(uniqueSeversList, sever)
|
||||
}
|
||||
|
||||
return uniqueVulnsList, uniqueSeversList
|
||||
}
|
||||
|
||||
func (ks *Kubescape) ScanImage(ctx context.Context, imgScanInfo *ksmetav1.ImageScanInfo, scanInfo *cautils.ScanInfo) (*models.PresenterConfig, error) {
|
||||
@@ -97,6 +106,7 @@ func (ks *Kubescape) ScanImage(ctx context.Context, imgScanInfo *ksmetav1.ImageS
|
||||
}
|
||||
|
||||
var vulnerabilityExceptions []string
|
||||
var severityExceptions []string
|
||||
if imgScanInfo.Exceptions != "" {
|
||||
exceptionPolicies, err := GetImageExceptionsFromFile(imgScanInfo.Exceptions)
|
||||
if err != nil {
|
||||
@@ -104,10 +114,10 @@ func (ks *Kubescape) ScanImage(ctx context.Context, imgScanInfo *ksmetav1.ImageS
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vulnerabilityExceptions = getUniqueVulnerabilities(exceptionPolicies)
|
||||
vulnerabilityExceptions, severityExceptions = getUniqueVulnerabilitiesAndSeverities(exceptionPolicies)
|
||||
}
|
||||
|
||||
scanResults, err := svc.Scan(ctx, imgScanInfo.Image, creds, vulnerabilityExceptions)
|
||||
scanResults, err := svc.Scan(ctx, imgScanInfo.Image, creds, vulnerabilityExceptions, severityExceptions)
|
||||
if err != nil {
|
||||
logger.L().StopError(fmt.Sprintf("Failed to scan image: %s", imgScanInfo.Image))
|
||||
return nil, err
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ func (ks *Kubescape) Patch(ctx context.Context, patchInfo *ksmetav1.PatchInfo, s
|
||||
Password: patchInfo.Password,
|
||||
}
|
||||
// Scan the image
|
||||
scanResults, err := svc.Scan(ctx, patchInfo.Image, creds, nil)
|
||||
scanResults, err := svc.Scan(ctx, patchInfo.Image, creds, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -81,7 +81,7 @@ func (ks *Kubescape) Patch(ctx context.Context, patchInfo *ksmetav1.PatchInfo, s
|
||||
|
||||
logger.L().Start(fmt.Sprintf("Re-scanning image: %s", patchedImageName))
|
||||
|
||||
scanResultsPatched, err := svc.Scan(ctx, patchedImageName, creds, nil)
|
||||
scanResultsPatched, err := svc.Scan(ctx, patchedImageName, creds, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+1
-1
@@ -257,7 +257,7 @@ func scanImages(scanType cautils.ScanTypes, scanData *cautils.OPASessionObj, ctx
|
||||
|
||||
func scanSingleImage(ctx context.Context, img string, svc imagescan.Service, resultsHandling *resultshandling.ResultsHandler) error {
|
||||
|
||||
scanResults, err := svc.Scan(ctx, img, imagescan.RegistryCredentials{}, nil)
|
||||
scanResults, err := svc.Scan(ctx, img, imagescan.RegistryCredentials{}, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/adrg/xdg"
|
||||
"github.com/anchore/grype/grype"
|
||||
@@ -117,9 +118,40 @@ type Service struct {
|
||||
dbCfg db.Config
|
||||
}
|
||||
|
||||
func (s *Service) Scan(ctx context.Context, userInput string, creds RegistryCredentials, exceptions []string) (*models.PresenterConfig, error) {
|
||||
if exceptions == nil {
|
||||
exceptions = []string{}
|
||||
// Filter the remaing matches based on severity exceptions.
|
||||
func filterMatchesBasedOnSeverity(severityExceptions []string, remainingMatches match.Matches, store *store.Store) match.Matches {
|
||||
filteredMatches := match.NewMatches()
|
||||
|
||||
for m := range remainingMatches.Enumerate() {
|
||||
metadata, err := store.GetMetadata(m.Vulnerability.ID, m.Vulnerability.Namespace)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip this match if the severity of this match is present in severityExceptions.
|
||||
excludeSeverity := false
|
||||
for _, sever := range severityExceptions {
|
||||
if strings.ToUpper(metadata.Severity) == sever {
|
||||
excludeSeverity = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if !excludeSeverity {
|
||||
filteredMatches.Add(m)
|
||||
}
|
||||
}
|
||||
|
||||
return filteredMatches
|
||||
}
|
||||
|
||||
func (s *Service) Scan(ctx context.Context, userInput string, creds RegistryCredentials, vulnerabilityExceptions, severityExceptions []string) (*models.PresenterConfig, error) {
|
||||
if vulnerabilityExceptions == nil {
|
||||
vulnerabilityExceptions = []string{}
|
||||
}
|
||||
|
||||
if severityExceptions == nil {
|
||||
severityExceptions = []string{}
|
||||
}
|
||||
|
||||
var err error
|
||||
@@ -139,7 +171,7 @@ func (s *Service) Scan(ctx context.Context, userInput string, creds RegistryCred
|
||||
}
|
||||
|
||||
var ignoreRules []match.IgnoreRule
|
||||
for _, exception := range exceptions {
|
||||
for _, exception := range vulnerabilityExceptions {
|
||||
rule := match.IgnoreRule{
|
||||
Vulnerability: exception,
|
||||
}
|
||||
@@ -159,8 +191,10 @@ func (s *Service) Scan(ctx context.Context, userInput string, creds RegistryCred
|
||||
}
|
||||
}
|
||||
|
||||
filteredMatches := filterMatchesBasedOnSeverity(severityExceptions, *remainingMatches, store)
|
||||
|
||||
pb := models.PresenterConfig{
|
||||
Matches: *remainingMatches,
|
||||
Matches: filteredMatches,
|
||||
IgnoredMatches: ignoredMatches,
|
||||
Packages: packages,
|
||||
Context: pkgContext,
|
||||
|
||||
@@ -72,7 +72,7 @@ func TestScan(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
scanResults, err := svc.Scan(ctx, tc.image, creds, tc.exceptions)
|
||||
scanResults, err := svc.Scan(ctx, tc.image, creds, tc.exceptions, nil)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.IsType(t, &models.PresenterConfig{}, scanResults)
|
||||
|
||||
Reference in New Issue
Block a user