Skip to content
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
23 changes: 18 additions & 5 deletions pkg/report/table/summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (r *summaryRenderer) Render(report types.Report) {
t.SetHeaders(headers...)
t.SetAlignment(alignments...)

for _, result := range splitAggregatedPackages(report.Results) {
for _, result := range r.splitAggregatedPackages(report.Results) {
resultType := string(result.Type)
switch result.Class {
case types.ClassSecret:
Expand Down Expand Up @@ -232,7 +232,7 @@ func (r *summaryRenderer) showEmptyResultsWarning() {

// splitAggregatedPackages splits aggregated packages into different results with path as target.
// Other results will be returned as is.
func splitAggregatedPackages(results types.Results) types.Results {
func (r *summaryRenderer) splitAggregatedPackages(results types.Results) types.Results {
var newResults types.Results

for _, result := range results {
Expand All @@ -243,14 +243,22 @@ func splitAggregatedPackages(results types.Results) types.Results {
continue
}

newResults = append(newResults, splitAggregatedVulns(result)...)
newResults = append(newResults, r.splitAggregatedVulns(result)...)
newResults = append(newResults, splitAggregatedLicenses(result)...)

}
return newResults
}

func splitAggregatedVulns(result types.Result) types.Results {
func (r *summaryRenderer) splitAggregatedVulns(result types.Result) types.Results {
// Handle case when result doesn't contain Package
// cf. https://github.com/aquasecurity/trivy/discussions/8537
if len(result.Packages) == 0 && len(result.Vulnerabilities) > 0 {
r.logger.Warn("Packages not found unexpectedly", log.String("target", result.Target))
return types.Results{
result,
}
}
// Save packages to display them in the table even if no vulnerabilities were found
resultMap := lo.SliceToMap(result.Packages, func(pkg ftypes.Package) (string, *types.Result) {
filePath := rootJarFromPath(pkg.FilePath)
Expand All @@ -262,7 +270,12 @@ func splitAggregatedVulns(result types.Result) types.Results {
})
for _, vuln := range result.Vulnerabilities {
pkgPath := rootJarFromPath(vuln.PkgPath)
resultMap[pkgPath].Vulnerabilities = append(resultMap[pkgPath].Vulnerabilities, vuln)

if res, ok := resultMap[pkgPath]; !ok {
r.logger.Warn("Package not found unexpectedly", log.String("package_path", pkgPath), log.String("vuln_id", vuln.VulnerabilityID))
} else {
res.Vulnerabilities = append(res.Vulnerabilities, vuln)
}
}
newResults := lo.Values(resultMap)
sort.Slice(newResults, func(i, j int) bool {
Expand Down
91 changes: 91 additions & 0 deletions pkg/report/table/summary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,49 @@ var (
},
}

jarVulnsWithoutPackages = types.Result{
Target: "Java",
Class: types.ClassLangPkg,
Type: ftypes.Jar,
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2022-42003",
PkgName: "com.fasterxml.jackson.core:jackson-databind",
PkgPath: "app/jackson-databind-2.13.4.1.jar",
},
{
VulnerabilityID: "CVE-2021-44832",
PkgName: "org.apache.logging.log4j:log4j-core",
PkgPath: "app/jackson-databind-2.13.4.1.jar/nested/app2/log4j-core-2.17.0.jar",
},
},
}

jarVulnsWithMissedPackage = types.Result{
Target: "Java",
Class: types.ClassLangPkg,
Type: ftypes.Jar,
Packages: []ftypes.Package{
{
Name: "com.fasterxml.jackson.core:jackson-databind",
Version: "2.13.4.1",
FilePath: "app/jackson-databind-2.13.4.1.jar",
},
},
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2022-42003",
PkgName: "com.fasterxml.jackson.core:jackson-databind",
PkgPath: "app/jackson-databind-2.13.4.1.jar",
},
{
VulnerabilityID: "CVE-2021-44832",
PkgName: "org.apache.logging.log4j:log4j-core",
PkgPath: "app/log4j-core-2.17.0.jar",
},
},
}

npmVulns = types.Result{
Target: "Node.js",
Class: types.ClassLangPkg,
Expand Down Expand Up @@ -285,6 +328,54 @@ Legend:
- '-': Not scanned
- '0': Clean (no security findings detected)

`,
},
{
name: "happy path when Result doesn't include Packages",
scanners: []types.Scanner{
types.VulnerabilityScanner,
},
report: types.Report{
Results: []types.Result{
jarVulnsWithoutPackages,
},
},
want: `
Report Summary

┌────────┬──────┬─────────────────┐
│ Target │ Type │ Vulnerabilities │
├────────┼──────┼─────────────────┤
│ Java │ jar │ 2 │
└────────┴──────┴─────────────────┘
Legend:
- '-': Not scanned
- '0': Clean (no security findings detected)

`,
},
{
name: "happy path when Result doesn't include all required Packages",
scanners: []types.Scanner{
types.VulnerabilityScanner,
},
report: types.Report{
Results: []types.Result{
jarVulnsWithMissedPackage,
},
},
want: `
Report Summary

┌───────────────────────────────────┬──────┬─────────────────┐
│ Target │ Type │ Vulnerabilities │
├───────────────────────────────────┼──────┼─────────────────┤
│ app/jackson-databind-2.13.4.1.jar │ jar │ 1 │
└───────────────────────────────────┴──────┴─────────────────┘
Legend:
- '-': Not scanned
- '0': Clean (no security findings detected)

`,
},
{
Expand Down