diff --git a/docs/docs/scanner/vulnerability/language/java.md b/docs/docs/scanner/vulnerability/language/java.md index 60e2ae402b..b09b4dcee0 100644 --- a/docs/docs/scanner/vulnerability/language/java.md +++ b/docs/docs/scanner/vulnerability/language/java.md @@ -26,6 +26,8 @@ It is stored in [the cache directory](../../../configuration/cache.md#cache-dire Base JAR[^2] may contain inner JARs[^2] within itself. To find information about these JARs[^2], the same logic is used as for the base JAR[^2]. +`table` format only contains the name of root JAR[^2] . To get the full path to inner JARs[^2] use the `json` format. + ## pom.xml Trivy parses your `pom.xml` file and tries to find files with dependencies from these local locations. diff --git a/go.mod b/go.mod index 0b4257abca..8bca0cdf54 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/alicebob/miniredis/v2 v2.30.1 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 github.com/aquasecurity/defsec v0.85.0 - github.com/aquasecurity/go-dep-parser v0.0.0-20230413091456-df0396537e15 + github.com/aquasecurity/go-dep-parser v0.0.0-20230424075837-ff3c67fd1ac8 github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 diff --git a/go.sum b/go.sum index 912bc8cd50..2e66176d93 100644 --- a/go.sum +++ b/go.sum @@ -321,8 +321,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30 github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8= github.com/aquasecurity/defsec v0.85.0 h1:2HZSWbmVK95iDaEok0EpZlXLjBTFTux1a3JGwAMyhLE= github.com/aquasecurity/defsec v0.85.0/go.mod h1:6bb5hLBkDyRlsObkKX4nybiDiCYX/AhrrSIklnPZzBg= -github.com/aquasecurity/go-dep-parser v0.0.0-20230413091456-df0396537e15 h1:umuByPARbGs3sE9BgtrDg6n0rR//O79ONFuWG+SU88I= -github.com/aquasecurity/go-dep-parser v0.0.0-20230413091456-df0396537e15/go.mod h1:lI+o04X85vxgx2jPji9G0tZ6AqqhVcXn8A88qimWfOM= +github.com/aquasecurity/go-dep-parser v0.0.0-20230424075837-ff3c67fd1ac8 h1:V7uFbekZ/LsOebpGMhz25GKMlq/lCXLH8RI5jBaCU00= +github.com/aquasecurity/go-dep-parser v0.0.0-20230424075837-ff3c67fd1ac8/go.mod h1:lI+o04X85vxgx2jPji9G0tZ6AqqhVcXn8A88qimWfOM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM= github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s= github.com/aquasecurity/go-mock-aws v0.0.0-20230328195059-5bf52338aec3 h1:Vt9y1gZS5JGY3tsL9zc++Cg4ofX51CG7PaMyC5SXWPg= diff --git a/integration/testdata/spring4shell-jre11.json.golden b/integration/testdata/spring4shell-jre11.json.golden index 1f2911dbbe..c2ab0c51d5 100644 --- a/integration/testdata/spring4shell-jre11.json.golden +++ b/integration/testdata/spring4shell-jre11.json.golden @@ -196,7 +196,7 @@ { "VulnerabilityID": "CVE-2022-22965", "PkgName": "org.springframework:spring-beans", - "PkgPath": "usr/local/tomcat/webapps/helloworld.war", + "PkgPath": "usr/local/tomcat/webapps/helloworld.war/WEB-INF/lib/spring-beans-5.3.15.jar", "InstalledVersion": "5.3.15", "FixedVersion": "5.3.18", "Layer": { diff --git a/integration/testdata/spring4shell-jre8.json.golden b/integration/testdata/spring4shell-jre8.json.golden index aaf906adc1..afdd5e4385 100644 --- a/integration/testdata/spring4shell-jre8.json.golden +++ b/integration/testdata/spring4shell-jre8.json.golden @@ -196,7 +196,7 @@ { "VulnerabilityID": "CVE-2022-22965", "PkgName": "org.springframework:spring-beans", - "PkgPath": "usr/local/tomcat/webapps/helloworld.war", + "PkgPath": "usr/local/tomcat/webapps/helloworld.war/WEB-INF/lib/spring-beans-5.3.15.jar", "InstalledVersion": "5.3.15", "FixedVersion": "5.3.18", "Layer": { diff --git a/pkg/fanal/analyzer/language/analyze.go b/pkg/fanal/analyzer/language/analyze.go index 950119610d..1d8c40f587 100644 --- a/pkg/fanal/analyzer/language/analyze.go +++ b/pkg/fanal/analyzer/language/analyze.go @@ -105,11 +105,17 @@ func toApplication(fileType, filePath, libFilePath string, r dio.ReadSeekerAt, l } locs = append(locs, l) } + + // This file path is populated for virtual file paths within archives, such as nested JAR files. + libPath := libFilePath + if lib.FilePath != "" { + libPath = lib.FilePath + } pkgs = append(pkgs, types.Package{ ID: lib.ID, Name: lib.Name, Version: lib.Version, - FilePath: libFilePath, + FilePath: libPath, Indirect: lib.Indirect, Licenses: licenses, DependsOn: deps[lib.ID], diff --git a/pkg/fanal/analyzer/language/java/jar/jar_test.go b/pkg/fanal/analyzer/language/java/jar/jar_test.go index 6e50d7b9a5..c4219875ec 100644 --- a/pkg/fanal/analyzer/language/java/jar/jar_test.go +++ b/pkg/fanal/analyzer/language/java/jar/jar_test.go @@ -40,37 +40,37 @@ func Test_javaLibraryAnalyzer_Analyze(t *testing.T) { Libraries: []types.Package{ { Name: "org.glassfish:javax.el", - FilePath: "testdata/test.war", + FilePath: "testdata/test.war/WEB-INF/lib/javax.el-3.0.0.jar", Version: "3.0.0", }, { Name: "com.fasterxml.jackson.core:jackson-databind", - FilePath: "testdata/test.war", + FilePath: "testdata/test.war/WEB-INF/lib/jackson-databind-2.9.10.6.jar", Version: "2.9.10.6", }, { Name: "com.fasterxml.jackson.core:jackson-annotations", - FilePath: "testdata/test.war", + FilePath: "testdata/test.war/WEB-INF/lib/jackson-annotations-2.9.10.jar", Version: "2.9.10", }, { Name: "com.fasterxml.jackson.core:jackson-core", - FilePath: "testdata/test.war", + FilePath: "testdata/test.war/WEB-INF/lib/jackson-core-2.9.10.jar", Version: "2.9.10", }, { Name: "org.slf4j:slf4j-api", - FilePath: "testdata/test.war", + FilePath: "testdata/test.war/WEB-INF/lib/slf4j-api-1.7.30.jar", Version: "1.7.30", }, { Name: "com.cronutils:cron-utils", - FilePath: "testdata/test.war", + FilePath: "testdata/test.war/WEB-INF/lib/cron-utils-9.1.2.jar", Version: "9.1.2", }, { Name: "org.apache.commons:commons-lang3", - FilePath: "testdata/test.war", + FilePath: "testdata/test.war/WEB-INF/lib/commons-lang3-3.11.jar", Version: "3.11", }, { @@ -95,7 +95,7 @@ func Test_javaLibraryAnalyzer_Analyze(t *testing.T) { Libraries: []types.Package{ { Name: "com.fasterxml.jackson.core:jackson-core", - FilePath: "testdata/test.par", + FilePath: "testdata/test.par/lib/jackson-core-2.9.10.jar", Version: "2.9.10", Digest: "sha1:d40913470259cfba6dcc90f96bcaa9bcff1b72e0", }, diff --git a/pkg/report/table/vulnerability.go b/pkg/report/table/vulnerability.go index 52c1580227..1c5aadbb1d 100644 --- a/pkg/report/table/vulnerability.go +++ b/pkg/report/table/vulnerability.go @@ -11,6 +11,7 @@ import ( "github.com/samber/lo" "github.com/xlab/treeprint" "golang.org/x/exp/maps" + "golang.org/x/exp/slices" "github.com/aquasecurity/table" "github.com/aquasecurity/tml" @@ -87,7 +88,10 @@ func (r *vulnerabilityRenderer) setVulnerabilityRows(vulns []types.DetectedVulne for _, v := range vulns { lib := v.PkgName if v.PkgPath != "" { - fileName := filepath.Base(v.PkgPath) + // get path to root jar + // for other languages return unchanged path + pkgPath := rootJarFromPath(v.PkgPath) + fileName := filepath.Base(pkgPath) lib = fmt.Sprintf("%s (%s)", v.PkgName, fileName) r.once.Do(func() { log.Logger.Infof("Table result includes only package filenames. Use '--format json' option to get the full path to the package file.") @@ -271,3 +275,16 @@ func findAncestor(pkgID string, parentMap map[string]ftypes.Packages, seen map[s } return maps.Keys(ancestors) } + +var jarExtensions = []string{".jar", ".war", ".par", ".ear"} + +func rootJarFromPath(path string) string { + // File paths are always forward-slashed in Trivy + paths := strings.Split(path, "/") + for i, p := range paths { + if slices.Contains(jarExtensions, filepath.Ext(p)) { + return strings.Join(paths[:i+1], "/") + } + } + return path +}