mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-05 20:40:16 -08:00
fix(report): don't panic when report contains vulns, but doesn't contain packages for table format (#8549)
This commit is contained in:
@@ -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:
|
||||
@@ -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 {
|
||||
@@ -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)
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
@@ -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)
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user