From 29fc583756e0568356ea9c7f8f7668f02df3ad26 Mon Sep 17 00:00:00 2001 From: DmitriyLewen Date: Wed, 6 Nov 2024 17:22:21 +0600 Subject: [PATCH] fix: use `pkgName:pkgVersion` for dep tree of pom packages --- pkg/report/table/vulnerability.go | 23 +++- pkg/report/table/vulnerability_test.go | 152 +++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 5 deletions(-) diff --git a/pkg/report/table/vulnerability.go b/pkg/report/table/vulnerability.go index 450349ed5fcb..aaf30a2a900b 100644 --- a/pkg/report/table/vulnerability.go +++ b/pkg/report/table/vulnerability.go @@ -10,6 +10,7 @@ import ( "strings" "sync" + "github.com/aquasecurity/trivy/pkg/dependency" "github.com/fatih/color" "github.com/samber/lo" "github.com/xlab/treeprint" @@ -276,10 +277,10 @@ Dependency Origin Tree (Reversed) // Render tree for _, vulnPkg := range vulnPkgs { _, summaries := summarize(r.severities, pkgSeverityCount[vulnPkg.ID]) - topLvlID := tml.Sprintf("%s, (%s)", vulnPkg.ID, strings.Join(summaries, ", ")) + topLvlID := tml.Sprintf("%s, (%s)", r.pkgID(vulnPkg), strings.Join(summaries, ", ")) branch := root.AddBranch(topLvlID) - addParents(branch, vulnPkg, parents, ancestors, map[string]struct{}{vulnPkg.ID: {}}, 1) + r.addParents(branch, vulnPkg, parents, ancestors, map[string]struct{}{vulnPkg.ID: {}}, 1) } r.printf(root.String()) @@ -290,7 +291,7 @@ func (r *vulnerabilityRenderer) printf(format string, args ...any) { _ = tml.Fprintf(r.w, format, args...) } -func addParents(topItem treeprint.Tree, pkg ftypes.Package, parentMap map[string]ftypes.Packages, ancestors map[string][]string, +func (r *vulnerabilityRenderer) addParents(topItem treeprint.Tree, pkg ftypes.Package, parentMap map[string]ftypes.Packages, ancestors map[string][]string, seen map[string]struct{}, depth int) { if pkg.Relationship == ftypes.RelationshipDirect { return @@ -304,7 +305,7 @@ func addParents(topItem treeprint.Tree, pkg ftypes.Package, parentMap map[string seen[parent.ID] = struct{}{} // to avoid infinite loops if depth == 1 && parent.Relationship == ftypes.RelationshipDirect { - topItem.AddBranch(parent.ID) + topItem.AddBranch(r.pkgID(parent)) } else { // We omit intermediate dependencies and show only direct dependencies // as this could make the dependency tree huge. @@ -323,11 +324,23 @@ func addParents(topItem treeprint.Tree, pkg ftypes.Package, parentMap map[string if len(rootIDs) > 0 { branch := topItem.AddBranch("...(omitted)...") for _, rootID := range rootIDs { - branch.AddBranch(rootID) + rootIDPkg, _ := lo.Find(r.result.Packages, func(pkg ftypes.Package) bool { + return pkg.ID == rootID + }) + branch.AddBranch(r.pkgID(rootIDPkg)) } } } +// pkgID overwrites ID for pom packages. +// This is required to overwrite UUIDs to maven (:) format. +func (r *vulnerabilityRenderer) pkgID(pkg ftypes.Package) string { + if r.result.Type != ftypes.Pom { + return pkg.ID + } + return dependency.ID(r.result.Type, pkg.Name, pkg.Version) +} + func traverseAncestors(pkgs []ftypes.Package, parentMap map[string]ftypes.Packages) map[string][]string { ancestors := make(map[string][]string) for _, pkg := range pkgs { diff --git a/pkg/report/table/vulnerability_test.go b/pkg/report/table/vulnerability_test.go index 9a773c90eafe..c24d429267ed 100644 --- a/pkg/report/table/vulnerability_test.go +++ b/pkg/report/table/vulnerability_test.go @@ -259,6 +259,158 @@ package-lock.json │ └── ...(omitted)... │ └── styled-components@3.1.3 └── sanitize-html@1.20.0, (MEDIUM: 1, HIGH: 0) +`, + }, + { + name: "happy path with vulnerability origin graph for pom.xml file with modules", + result: types.Result{ + Target: "pom.xml", + Class: types.ClassLangPkg, + Type: "pom", + Packages: []ftypes.Package{ + { + ID: "3ff14136-e09f-4df9-80ea-000000000001", + Name: "com.example:root", + Version: "0.0.1", + Relationship: ftypes.RelationshipRoot, + DependsOn: []string{ + "3ff14136-e09f-4df9-80ea-000000000003", + }, + }, + // module1 + { + ID: "3ff14136-e09f-4df9-80ea-000000000002", + Name: "com.example:module1", + Version: "1.0.0", + Relationship: ftypes.RelationshipRoot, + DependsOn: []string{ + "3ff14136-e09f-4df9-80ea-000000000003", + }, + }, + { + ID: "3ff14136-e09f-4df9-80ea-000000000003", + Name: "org.apache.logging.log4j:log4j-core", + Version: "2.6.1", + Relationship: ftypes.RelationshipDirect, + }, + // module2 + { + ID: "3ff14136-e09f-4df9-80ea-000000000004", + Name: "com.example:module2", + Version: "2.0.0", + Relationship: ftypes.RelationshipRoot, + DependsOn: []string{ + "3ff14136-e09f-4df9-80ea-000000000005", + }, + }, + { + ID: "3ff14136-e09f-4df9-80ea-000000000005", + Name: "com.example:example-dependency", + Version: "2.0.0", + Relationship: ftypes.RelationshipDirect, + DependsOn: []string{ + "3ff14136-e09f-4df9-80ea-000000000006", + }, + }, + { + ID: "3ff14136-e09f-4df9-80ea-000000000006", + Name: "org.apache.logging.log4j:log4j-core", + Version: "2.6.1", + Relationship: ftypes.RelationshipIndirect, + }, + // Root pkg + { + ID: "3ff14136-e09f-4df9-80ea-000000000007", + Name: "com.example:example-nested-dependency", + Version: "2.0.0", + Relationship: ftypes.RelationshipDirect, + DependsOn: []string{ + "3ff14136-e09f-4df9-80ea-000000000008", + }, + }, + { + ID: "3ff14136-e09f-4df9-80ea-000000000008", + Name: "com.example:example-dependency", + Version: "2.0.0", + Relationship: ftypes.RelationshipIndirect, + DependsOn: []string{ + "3ff14136-e09f-4df9-80ea-000000000009", + }, + }, + + { + ID: "3ff14136-e09f-4df9-80ea-000000000009", + Name: "org.apache.logging.log4j:log4j-core", + Version: "2.6.1", + Relationship: ftypes.RelationshipIndirect, + }, + }, + Vulnerabilities: []types.DetectedVulnerability{ + { + VulnerabilityID: "CVE-2017-5645", + PkgID: "3ff14136-e09f-4df9-80ea-000000000003", + PkgName: "org.apache.logging.log4j:log4j-core", + Vulnerability: dbTypes.Vulnerability{ + Title: "foobar", + Description: "baz", + Severity: "HIGH", + }, + InstalledVersion: "2.6.1", + FixedVersion: "2.8.2", + Status: dbTypes.StatusFixed, + }, + { + VulnerabilityID: "CVE-2017-5645", + PkgID: "3ff14136-e09f-4df9-80ea-000000000006", + PkgName: "org.apache.logging.log4j:log4j-core", + Vulnerability: dbTypes.Vulnerability{ + Title: "foobar", + Description: "baz", + Severity: "HIGH", + }, + InstalledVersion: "2.6.1", + FixedVersion: "2.8.2", + Status: dbTypes.StatusFixed, + }, + { + VulnerabilityID: "CVE-2017-5645", + PkgID: "3ff14136-e09f-4df9-80ea-000000000009", + PkgName: "org.apache.logging.log4j:log4j-core", + Vulnerability: dbTypes.Vulnerability{ + Title: "foobar", + Description: "baz", + Severity: "HIGH", + }, + InstalledVersion: "2.6.1", + FixedVersion: "2.8.2", + Status: dbTypes.StatusFixed, + }, + }, + }, + want: ` +pom.xml (pom) +============= +Total: 3 (MEDIUM: 0, HIGH: 3) + +┌─────────────────────────────────────┬───────────────┬──────────┬────────┬───────────────────┬───────────────┬────────┐ +│ Library │ Vulnerability │ Severity │ Status │ Installed Version │ Fixed Version │ Title │ +├─────────────────────────────────────┼───────────────┼──────────┼────────┼───────────────────┼───────────────┼────────┤ +│ org.apache.logging.log4j:log4j-core │ CVE-2017-5645 │ HIGH │ fixed │ 2.6.1 │ 2.8.2 │ foobar │ +│ │ │ │ │ │ │ │ +│ │ │ │ │ │ │ │ +│ │ │ │ │ │ │ │ +│ │ │ │ │ │ │ │ +└─────────────────────────────────────┴───────────────┴──────────┴────────┴───────────────────┴───────────────┴────────┘ + +Dependency Origin Tree (Reversed) +================================= +pom.xml +├── org.apache.logging.log4j:log4j-core:2.6.1, (MEDIUM: 0, HIGH: 1) +├── org.apache.logging.log4j:log4j-core:2.6.1, (MEDIUM: 0, HIGH: 1) +│ └── com.example:example-dependency:2.0.0 +└── org.apache.logging.log4j:log4j-core:2.6.1, (MEDIUM: 0, HIGH: 1) + └── ...(omitted)... + └── com.example:example-nested-dependency:2.0.0 `, }, {