Skip to content

Commit

Permalink
feat(java): add empty versions if pom.xml dependency versions can't…
Browse files Browse the repository at this point in the history
… be detected (#7520)

Co-authored-by: Teppei Fukuda <knqyf263@gmail.com>
  • Loading branch information
DmitriyLewen and knqyf263 authored Sep 30, 2024
1 parent 60725f8 commit b836232
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 2 deletions.
11 changes: 11 additions & 0 deletions docs/docs/coverage/language/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ The vulnerability database will be downloaded anyway.
!!! Warning
Trivy may skip some dependencies (that were not found on your local machine) when the `--offline-scan` flag is passed.

### empty dependency version
There are cases when Trivy cannot determine the version of dependencies:

- Unable to determine the version from the parent because the parent is not reachable;
- The dependency uses a [hard requirement][version-requirement] with more than one version.

In these cases, Trivy uses an empty version for the dependency.

!!! Warning
Trivy doesn't detect child dependencies for dependencies without a version.

### maven-invoker-plugin
Typically, the integration tests directory (`**/[src|target]/it/*/pom.xml`) of [maven-invoker-plugin][maven-invoker-plugin] doesn't contain actual `pom.xml` files and should be skipped to avoid noise.
Expand Down Expand Up @@ -120,3 +130,4 @@ Make sure that you have cache[^8] directory to find licenses from `*.pom` depend
[maven-pom-repos]: https://maven.apache.org/settings.html#repositories
[sbt-dependency-lock]: https://stringbean.github.io/sbt-dependency-lock
[detection-priority]: ../../scanner/vulnerability.md#detection-priority
[version-requirement]: https://maven.apache.org/pom.html#dependency-version-requirement-specification
21 changes: 19 additions & 2 deletions pkg/dependency/parser/java/pom/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@ import (
"regexp"
"slices"
"strings"
"sync"

"github.com/samber/lo"

ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/version/doc"
)

var (
varRegexp = regexp.MustCompile(`\${(\S+?)}`)
varRegexp = regexp.MustCompile(`\${(\S+?)}`)
emptyVersionWarn = sync.OnceFunc(func() {
log.WithPrefix("pom").Warn("Dependency version cannot be determined. Child dependencies will not be found.",
// e.g. https://aquasecurity.github.io/trivy/latest/docs/coverage/language/java/#empty-dependency-version
log.String("details", doc.URL("/docs/coverage/language/java/", "empty-dependency-version")))
})
)

type artifact struct {
Expand Down Expand Up @@ -42,7 +49,17 @@ func newArtifact(groupID, artifactID, version string, licenses []string, props m
}

func (a artifact) IsEmpty() bool {
return a.GroupID == "" || a.ArtifactID == "" || a.Version.String() == ""
if a.GroupID == "" || a.ArtifactID == "" {
return true
}
if a.Version.String() == "" {
emptyVersionWarn()
log.WithPrefix("pom").Debug("Dependency version cannot be determined.",
log.String("GroupID", a.GroupID),
log.String("ArtifactID", a.ArtifactID),
)
}
return false
}

func (a artifact) Equal(o artifact) bool {
Expand Down
8 changes: 8 additions & 0 deletions pkg/dependency/parser/java/pom/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ func (p *Parser) resolve(art artifact, rootDepManagement []pomDependency) (analy
return *result, nil
}

// We can't resolve a dependency without a version.
// So let's just keep this dependency.
if art.Version.String() == "" {
return analysisResult{
artifact: art,
}, nil
}

p.logger.Debug("Resolving...", log.String("group_id", art.GroupID),
log.String("artifact_id", art.ArtifactID), log.String("version", art.Version.String()))
pomContent, err := p.tryRepository(art.GroupID, art.ArtifactID, art.Version.String())
Expand Down
35 changes: 35 additions & 0 deletions pkg/dependency/parser/java/pom/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,17 @@ func TestPom_Parse(t *testing.T) {
Licenses: []string{"Apache 2.0"},
Relationship: ftypes.RelationshipRoot,
},
{
ID: "org.example:example-api",
Name: "org.example:example-api",
Relationship: ftypes.RelationshipDirect,
Locations: []ftypes.Location{
{
StartLine: 28,
EndLine: 32,
},
},
},
},
},
{
Expand Down Expand Up @@ -1499,6 +1510,30 @@ func TestPom_Parse(t *testing.T) {
},
},
},
{
name: "dependency without version",
inputFile: filepath.Join("testdata", "dep-without-version", "pom.xml"),
local: true,
want: []ftypes.Package{
{
ID: "com.example:dep-without-version:1.0.0",
Name: "com.example:dep-without-version",
Version: "1.0.0",
Relationship: ftypes.RelationshipRoot,
},
{
ID: "org.example:example-api",
Name: "org.example:example-api",
Relationship: ftypes.RelationshipDirect,
Locations: ftypes.Locations{
{
StartLine: 19,
EndLine: 22,
},
},
},
},
},
// [INFO] com.example:root-depManagement-in-parent:jar:1.0.0
// [INFO] \- org.example:example-dependency:jar:2.0.0:compile
// [INFO] \- org.example:example-api:jar:1.0.1:compile
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<name>no-parent</name>
<description>Parent not found</description>

<parent>
<groupId>com.example</groupId>
<artifactId>wrong-parent</artifactId>
<version>1.0.0</version>
</parent>

<groupId>com.example</groupId>
<artifactId>dep-without-version</artifactId>
<version>1.0.0</version>

<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-api</artifactId>
</dependency>
</dependencies>
</project>
11 changes: 11 additions & 0 deletions pkg/fanal/analyzer/language/java/pom/pom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ func Test_pomAnalyzer_Analyze(t *testing.T) {
Licenses: []string{"Apache-2.0"},
Relationship: types.RelationshipRoot,
},
{
ID: "org.example:example-api",
Name: "org.example:example-api",
Relationship: types.RelationshipDirect,
Locations: []types.Location{
{
StartLine: 21,
EndLine: 25,
},
},
},
},
},
},
Expand Down

0 comments on commit b836232

Please sign in to comment.