diff --git a/core/core/scan.go b/core/core/scan.go index 6b75137f..cd7c1f3e 100644 --- a/core/core/scan.go +++ b/core/core/scan.go @@ -21,6 +21,7 @@ import ( "github.com/kubescape/kubescape/v2/pkg/imagescan" apisv1 "github.com/kubescape/opa-utils/httpserver/apis/v1" "go.opentelemetry.io/otel" + "golang.org/x/exp/slices" "github.com/kubescape/opa-utils/resources" ) @@ -226,17 +227,17 @@ func scanImages(scanInfo *cautils.ScanInfo, scanData *cautils.OPASessionObj, ctx if scanInfo.ScanType == cautils.ScanTypeWorkload { containers, _ := workloadinterface.NewWorkloadObj(scanData.ScannedWorkload.GetObject()).GetContainers() for _, container := range containers { - // if !slices.Contains(imagesToScan, container.Image) { - imagesToScan = append(imagesToScan, container.Image) - // } + if !slices.Contains(imagesToScan, container.Image) { + imagesToScan = append(imagesToScan, container.Image) + } } } else { for _, workload := range scanData.AllResources { containers, _ := workloadinterface.NewWorkloadObj(workload.GetObject()).GetContainers() for _, container := range containers { - // if !slices.Contains(imagesToScan, container.Image) { - imagesToScan = append(imagesToScan, container.Image) - // } + if !slices.Contains(imagesToScan, container.Image) { + imagesToScan = append(imagesToScan, container.Image) + } } } } diff --git a/core/pkg/resultshandling/printer/v2/prettyprinter.go b/core/pkg/resultshandling/printer/v2/prettyprinter.go index 0229771b..50b8910d 100644 --- a/core/pkg/resultshandling/printer/v2/prettyprinter.go +++ b/core/pkg/resultshandling/printer/v2/prettyprinter.go @@ -93,11 +93,11 @@ func (pp *PrettyPrinter) convertToImageScanSummary(imageScanData []cautils.Image continue } - imageScanSummary.CVEs = extractCVEs(doc.Matches) + imageScanSummary.CVEs = append(imageScanSummary.CVEs, extractCVEs(doc.Matches)...) - imageScanSummary.PackageScores = extractPkgNameToScoreMap(doc.Matches) + extractPkgNameToScoreMap(doc.Matches, imageScanSummary.PackageScores) - imageScanSummary.MapsSeverityToSummary = extractSeverityToSummaryMap(imageScanSummary.CVEs) + extractSeverityToSummaryMap(imageScanSummary.CVEs, imageScanSummary.MapsSeverityToSummary) } return &imageScanSummary, nil diff --git a/core/pkg/resultshandling/printer/v2/prettyprinter/utils.go b/core/pkg/resultshandling/printer/v2/prettyprinter/utils.go index c34f46d9..88a72c6c 100644 --- a/core/pkg/resultshandling/printer/v2/prettyprinter/utils.go +++ b/core/pkg/resultshandling/printer/v2/prettyprinter/utils.go @@ -113,32 +113,6 @@ func filterCVEsBySeverities(cves []imageprinter.CVE, severities []string) []imag return filteredCVEs } -// sortTopVulnerablePackages sorts the top vulnerable packages by score. It return a map of packages to their score and version -func sortTopVulnerablePackages(pkgScores map[string]*imageprinter.PackageScore) map[string]*imageprinter.PackageScore { - var ss []string - for k := range pkgScores { - ss = append(ss, k) - } - - sort.Slice(ss, func(i, j int) bool { - return pkgScores[ss[i]].Score > pkgScores[ss[j]].Score - }) - - var sortedMap = make(map[string]*imageprinter.PackageScore) - - for i := 0; i < len(ss) && i < TopPackagesNumber; i++ { - sortedMap[ss[i]] = &imageprinter.PackageScore{ - Name: pkgScores[ss[i]].Name, - Score: pkgScores[ss[i]].Score, - Version: pkgScores[ss[i]].Version, - MapSeverityToCVEsNumber: pkgScores[ss[i]].MapSeverityToCVEsNumber, - } - } - - return sortedMap -} - -// / PRINTERS /// func printTopVulnerabilities(writer *os.File, summary imageprinter.ImageScanSummary) { if len(summary.PackageScores) == 0 { return @@ -146,16 +120,28 @@ func printTopVulnerabilities(writer *os.File, summary imageprinter.ImageScanSumm cautils.InfoTextDisplay(writer, "\nMost vulnerable components:\n") - topVulnerablePackages := sortTopVulnerablePackages(summary.PackageScores) + var ss []string + for k := range summary.PackageScores { + ss = append(ss, k) + } - for _, v := range topVulnerablePackages { - output := fmt.Sprintf(" * %s (%s) -", v.Name, v.Version) - for severity, numberOfCVEs := range v.MapSeverityToCVEsNumber { + sort.Slice(ss, func(i, j int) bool { + if summary.PackageScores[ss[i]].Score == summary.PackageScores[ss[j]].Score { + return summary.PackageScores[ss[i]].Name < summary.PackageScores[ss[j]].Name + } + return summary.PackageScores[ss[i]].Score > summary.PackageScores[ss[j]].Score + }) + + for i := 0; i < len(ss) && i < TopPackagesNumber; i++ { + topPkg := summary.PackageScores[ss[i]] + output := fmt.Sprintf(" * %s (%s) -", topPkg.Name, topPkg.Version) + for severity, numberOfCVEs := range topPkg.MapSeverityToCVEsNumber { output += fmt.Sprintf(" %d %s,", numberOfCVEs, severity) } output = output[:len(output)-1] cautils.SimpleDisplay(writer, output+"\n") + } cautils.SimpleDisplay(writer, "\n") diff --git a/core/pkg/resultshandling/printer/v2/utils.go b/core/pkg/resultshandling/printer/v2/utils.go index 261c7a9a..386e44cc 100644 --- a/core/pkg/resultshandling/printer/v2/utils.go +++ b/core/pkg/resultshandling/printer/v2/utils.go @@ -88,8 +88,7 @@ func finalizeResources(results []resourcesresults.Result, allResources map[strin } // returns map of severity to summary -func extractSeverityToSummaryMap(cves []imageprinter.CVE) map[string]*imageprinter.SeveritySummary { - mapSeverityToSummary := map[string]*imageprinter.SeveritySummary{} +func extractSeverityToSummaryMap(cves []imageprinter.CVE, mapSeverityToSummary map[string]*imageprinter.SeveritySummary) { for _, cve := range cves { if _, ok := mapSeverityToSummary[cve.Severity]; !ok { mapSeverityToSummary[cve.Severity] = &imageprinter.SeveritySummary{} @@ -99,29 +98,26 @@ func extractSeverityToSummaryMap(cves []imageprinter.CVE) map[string]*imageprint mapSeverityToSummary[cve.Severity].NumberOfFixableCVEs = mapSeverityToSummary[cve.Severity].NumberOfFixableCVEs + 1 } } - return mapSeverityToSummary } // returns a map of package name + version to score (we can have multiple matches for the same package with different versions) -func extractPkgNameToScoreMap(matches []models.Match) map[string]*imageprinter.PackageScore { - mapPackageNameToScore := make(map[string]*imageprinter.PackageScore, 0) +func extractPkgNameToScoreMap(matches []models.Match, pkgScores map[string]*imageprinter.PackageScore) { for i := range matches { key := matches[i].Artifact.Name + matches[i].Artifact.Version - if _, ok := mapPackageNameToScore[key]; !ok { - mapPackageNameToScore[key] = &imageprinter.PackageScore{ + if _, ok := pkgScores[key]; !ok { + pkgScores[key] = &imageprinter.PackageScore{ Version: matches[i].Artifact.Version, Name: matches[i].Artifact.Name, MapSeverityToCVEsNumber: make(map[string]int, 0), } } - if _, ok := mapPackageNameToScore[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity]; !ok { - mapPackageNameToScore[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity] = 1 + if _, ok := pkgScores[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity]; !ok { + pkgScores[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity] = 1 } else { - mapPackageNameToScore[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity] = mapPackageNameToScore[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity] + 1 + pkgScores[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity] = pkgScores[key].MapSeverityToCVEsNumber[matches[i].Vulnerability.Severity] + 1 } - mapPackageNameToScore[key].Score = mapPackageNameToScore[key].Score + utils.ImageSeverityToInt(matches[i].Vulnerability.Severity) + pkgScores[key].Score = pkgScores[key].Score + utils.ImageSeverityToInt(matches[i].Vulnerability.Severity) } - return mapPackageNameToScore } func extractCVEs(matches []models.Match) []imageprinter.CVE {