Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for gradle.lockfile #2759

Merged
merged 10 commits into from Sep 1, 2022
45 changes: 23 additions & 22 deletions docs/docs/vulnerability/detection/language.md
Expand Up @@ -2,28 +2,29 @@

`Trivy` automatically detects the following files in the container and scans vulnerabilities in the application dependencies.

| Language | File | Image[^8] | Rootfs[^9] | Filesystem[^10] | Repository[^11] | Dev dependencies |
| -------- |-------------------------| :-------: | :--------: | :-------------: | :-------------: | ---------------- |
| Ruby | Gemfile.lock | - | - ||| included |
| | gemspec ||| - | - | included |
| Python | Pipfile.lock | - | - ||| excluded |
| | poetry.lock | - | - ||| included |
| | requirements.txt | - | - ||| included |
| | egg package[^1] ||| - | - | excluded |
| | wheel package[^2] ||| - | - | excluded |
| PHP | composer.lock ||||| excluded |
| Node.js | package-lock.json | - | - ||| excluded |
| | yarn.lock | - | - ||| included |
| | pnpm-lock.yaml | - | - ||| excluded |
| | package.json ||| - | - | excluded |
| .NET | packages.lock.json ||||| included |
| | packages.config ||||| excluded |
| | .deps.json ||||| excluded |
| Java | JAR/WAR/PAR/EAR[^3][^4] ||| - | - | included |
| | pom.xml[^5] | - | - ||| excluded |
| Go | Binaries built by Go[^6] ||| - | - | excluded |
| | go.mod[^7] | - | - ||| included |
| Rust | Cargo.lock ||||| included |
| Language | File | Image[^8] | Rootfs[^9] | Filesystem[^10] | Repository[^11] | Dev dependencies |
| -------- |--------------------------------------------------------------------------------------------| :-------: | :--------: | :-------------: | :-------------: | ---------------- |
| Ruby | Gemfile.lock | - | - ||| included |
| | gemspec ||| - | - | included |
| Python | Pipfile.lock | - | - ||| excluded |
| | poetry.lock | - | - ||| included |
| | requirements.txt | - | - ||| included |
| | egg package[^1] ||| - | - | excluded |
| | wheel package[^2] ||| - | - | excluded |
| PHP | composer.lock ||||| excluded |
| Node.js | package-lock.json | - | - ||| excluded |
| | yarn.lock | - | - ||| included |
| | pnpm-lock.yaml | - | - ||| excluded |
| | package.json ||| - | - | excluded |
| .NET | packages.lock.json ||||| included |
| | packages.config ||||| excluded |
| | .deps.json ||||| excluded |
| Java | JAR/WAR/PAR/EAR[^3][^4] ||| - | - | included |
| | pom.xml[^5] | - | - ||| excluded |
| | *gradle.lockfile | - | - ||| excluded |
| Go | Binaries built by Go[^6] ||| - | - | excluded |
| | go.mod[^7] | - | - ||| included |
| Rust | Cargo.lock ||||| included |
| | Binaries built with [cargo-auditable](https://github.com/rust-secure-code/cargo-auditable) | ✅ | ✅ | - | - | excluded

The path of these files does not matter.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -8,7 +8,7 @@ require (
github.com/NYTimes/gziphandler v1.1.1
github.com/alicebob/miniredis/v2 v2.22.0
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/go-dep-parser v0.0.0-20220824115155-600849a106bd
github.com/aquasecurity/go-dep-parser v0.0.0-20220830123424-46cde9383d60
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
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -206,8 +206,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.71.9 h1:eo244v1RQzziClY9xXyVftPibE0fddXbTtkvH52/slU=
github.com/aquasecurity/defsec v0.71.9/go.mod h1:2jYgkIi3UFbkrbtpnr3Cu49JZ3MGuLMJAhyh63jV1I4=
github.com/aquasecurity/go-dep-parser v0.0.0-20220824115155-600849a106bd h1:jgYzIraCXhabEhYOmQRb73/YlyWGaGOktA5ZsZ7+6RE=
github.com/aquasecurity/go-dep-parser v0.0.0-20220824115155-600849a106bd/go.mod h1:6G1Y5nht5TL9kr1SzmrdE8PrmbNXo9nHx3qFR3qURg0=
github.com/aquasecurity/go-dep-parser v0.0.0-20220830123424-46cde9383d60 h1:lBkhapZtunGpC8yu2fjGvGXUNbB2pNgmn5XPuHrPxnw=
github.com/aquasecurity/go-dep-parser v0.0.0-20220830123424-46cde9383d60/go.mod h1:6G1Y5nht5TL9kr1SzmrdE8PrmbNXo9nHx3qFR3qURg0=
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-20220726154943-99847deb62b0 h1:tihCUjLWkF0b1SAjAKcFltUs3SpsqGrLtI+Frye0D10=
Expand Down
8 changes: 8 additions & 0 deletions integration/fs_test.go
Expand Up @@ -73,6 +73,14 @@ func TestFilesystem(t *testing.T) {
},
golden: "testdata/pom.json.golden",
},
{
name: "gradle",
args: args{
securityChecks: "vuln",
input: "testdata/fixtures/fs/gradle",
},
golden: "testdata/gradle.json.golden",
},
{
name: "dockerfile",
args: args{
Expand Down
5 changes: 5 additions & 0 deletions integration/testdata/fixtures/fs/gradle/gradle.lockfile
@@ -0,0 +1,5 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-databind:2.9.1=compileClasspath, runtimeClasspath
empty=
126 changes: 126 additions & 0 deletions integration/testdata/gradle.json.golden
@@ -0,0 +1,126 @@
{
"SchemaVersion": 2,
"ArtifactName": "testdata/fixtures/fs/gradle",
"ArtifactType": "filesystem",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
},
"Results": [
{
"Target": "gradle.lockfile",
"Class": "lang-pkgs",
"Type": "gradle",
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2020-9548",
"PkgName": "com.fasterxml.jackson.core:jackson-databind",
"InstalledVersion": "2.9.1",
"FixedVersion": "2.9.10.4",
"Layer": {},
"SeveritySource": "ghsa",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2020-9548",
"DataSource": {
"ID": "ghsa",
"Name": "GitHub Security Advisory Maven",
"URL": "https://github.com/advisories?query=type%3Areviewed+ecosystem%3Amaven"
},
"Title": "jackson-databind: Serialization gadgets in anteros-core",
"Description": "FasterXML jackson-databind 2.x before 2.9.10.4 mishandles the interaction between serialization gadgets and typing, related to br.com.anteros.dbcp.AnterosDBCPConfig (aka anteros-core).",
"Severity": "CRITICAL",
"CweIDs": [
"CWE-502"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:P",
"V3Vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"V2Score": 6.8,
"V3Score": 9.8
},
"redhat": {
"V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"V3Score": 8.1
}
},
"References": [
"https://access.redhat.com/security/cve/CVE-2020-9548",
"https://github.com/FasterXML/jackson-databind/issues/2634",
"https://github.com/advisories/GHSA-p43x-xfjf-5jhr",
"https://lists.apache.org/thread.html/r35d30db00440ef63b791c4b7f7acb036e14d4a23afa2a249cb66c0fd@%3Cissues.zookeeper.apache.org%3E",
"https://lists.apache.org/thread.html/r9464a40d25c3ba1a55622db72f113eb494a889656962d098c70c5bb1@%3Cdev.zookeeper.apache.org%3E",
"https://lists.apache.org/thread.html/r98c9b6e4c9e17792e2cd1ec3e4aa20b61a791939046d3f10888176bb@%3Cissues.zookeeper.apache.org%3E",
"https://lists.apache.org/thread.html/rb6fecb5e96a6d61e175ff49f33f2713798dd05cf03067c169d195596@%3Cissues.zookeeper.apache.org%3E",
"https://lists.apache.org/thread.html/rd5a4457be4623038c3989294429bc063eec433a2e55995d81591e2ca@%3Cissues.zookeeper.apache.org%3E",
"https://lists.apache.org/thread.html/rdd49ab9565bec436a896bc00c4b9fc9dce1598e106c318524fbdfec6@%3Cissues.zookeeper.apache.org%3E",
"https://lists.apache.org/thread.html/rdd4df698d5d8e635144d2994922bf0842e933809eae259521f3b5097@%3Cissues.zookeeper.apache.org%3E",
"https://lists.apache.org/thread.html/rf1bbc0ea4a9f014cf94df9a12a6477d24a27f52741dbc87f2fd52ff2@%3Cissues.geode.apache.org%3E",
"https://lists.debian.org/debian-lts-announce/2020/03/msg00008.html",
"https://medium.com/@cowtowncoder/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062",
"https://nvd.nist.gov/vuln/detail/CVE-2020-9548",
"https://security.netapp.com/advisory/ntap-20200904-0006/",
"https://www.oracle.com/security-alerts/cpujan2021.html",
"https://www.oracle.com/security-alerts/cpujul2020.html",
"https://www.oracle.com/security-alerts/cpuoct2020.html",
"https://www.oracle.com/security-alerts/cpuoct2021.html"
],
"PublishedDate": "2020-03-02T04:15:00Z",
"LastModifiedDate": "2021-12-02T21:23:00Z"
},
{
"VulnerabilityID": "CVE-2021-20190",
"PkgName": "com.fasterxml.jackson.core:jackson-databind",
"InstalledVersion": "2.9.1",
"FixedVersion": "2.9.10.7",
"Layer": {},
"SeveritySource": "nvd",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-20190",
"DataSource": {
"ID": "glad",
"Name": "GitLab Advisory Database Community",
"URL": "https://gitlab.com/gitlab-org/advisories-community"
},
"Title": "jackson-databind: mishandles the interaction between serialization gadgets and typing, related to javax.swing",
"Description": "A flaw was found in jackson-databind before 2.9.10.7. FasterXML mishandles the interaction between serialization gadgets and typing. The highest threat from this vulnerability is to data confidentiality and integrity as well as system availability.",
"Severity": "HIGH",
"CweIDs": [
"CWE-502"
],
"CVSS": {
"nvd": {
"V2Vector": "AV:N/AC:M/Au:N/C:P/I:P/A:C",
"V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"V2Score": 8.3,
"V3Score": 8.1
},
"redhat": {
"V3Vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"V3Score": 8.1
}
},
"References": [
"https://access.redhat.com/security/cve/CVE-2021-20190",
"https://bugzilla.redhat.com/show_bug.cgi?id=1916633",
"https://github.com/FasterXML/jackson-databind/commit/7dbf51bf78d157098074a20bd9da39bd48c18e4a",
"https://github.com/FasterXML/jackson-databind/issues/2854",
"https://github.com/advisories/GHSA-5949-rw7g-wx7w",
"https://lists.apache.org/thread.html/r380e9257bacb8551ee6fcf2c59890ae9477b2c78e553fa9ea08e9d9a@%3Ccommits.nifi.apache.org%3E",
"https://lists.debian.org/debian-lts-announce/2021/04/msg00025.html",
"https://nvd.nist.gov/vuln/detail/CVE-2021-20190",
"https://security.netapp.com/advisory/ntap-20210219-0008/"
],
"PublishedDate": "2021-01-19T17:15:00Z",
"LastModifiedDate": "2021-07-20T23:15:00Z"
}
]
}
]
}
2 changes: 1 addition & 1 deletion pkg/detector/library/driver.go
Expand Up @@ -37,7 +37,7 @@ func NewDriver(libType string) (Driver, error) {
case ftypes.GoBinary, ftypes.GoModule:
ecosystem = vulnerability.Go
comparer = compare.GenericComparer{}
case ftypes.Jar, ftypes.Pom:
case ftypes.Jar, ftypes.Pom, ftypes.Gradle:
ecosystem = vulnerability.Maven
comparer = maven.Comparer{}
case ftypes.Npm, ftypes.Yarn, ftypes.Pnpm, ftypes.NodePkg, ftypes.JavaScript:
Expand Down
1 change: 1 addition & 0 deletions pkg/fanal/analyzer/all/import.go
Expand Up @@ -7,6 +7,7 @@ import (
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/dotnet/nuget"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/binary"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/golang/mod"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/gradle"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/jar"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/java/pom"
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/nodejs/npm"
Expand Down
9 changes: 5 additions & 4 deletions pkg/fanal/analyzer/const.go
Expand Up @@ -47,8 +47,9 @@ const (
TypeComposer Type = "composer"

// Java
TypeJar Type = "jar"
TypePom Type = "pom"
TypeJar Type = "jar"
TypePom Type = "pom"
TypeGradleLock Type = "gradle-lockfile"

// Node.js
TypeNpmPkgLock Type = "npm"
Expand Down Expand Up @@ -113,15 +114,15 @@ var (

// TypeLanguages has all language analyzers
TypeLanguages = []Type{
TypeBundler, TypeGemSpec, TypeCargo, TypeComposer, TypeJar, TypePom,
TypeBundler, TypeGemSpec, TypeCargo, TypeComposer, TypeJar, TypePom, TypeGradleLock,
TypeNpmPkgLock, TypeNodePkg, TypeYarn, TypePnpm, TypeNuget, TypeDotNetDeps,
TypePythonPkg, TypePip, TypePipenv, TypePoetry, TypeGoBinary, TypeGoMod, TypeRustBinary,
}

// TypeLockfiles has all lock file analyzers
TypeLockfiles = []Type{
TypeBundler, TypeNpmPkgLock, TypeYarn,
TypePnpm, TypePip, TypePipenv, TypePoetry, TypeGoMod, TypePom,
TypePnpm, TypePip, TypePipenv, TypePoetry, TypeGoMod, TypePom, TypeGradleLock,
}

// TypeIndividualPkgs has all analyzers for individual packages
Expand Down
47 changes: 47 additions & 0 deletions pkg/fanal/analyzer/language/java/gradle/lockfile.go
@@ -0,0 +1,47 @@
package gradle

import (
"context"
"os"
"strings"

"github.com/aquasecurity/go-dep-parser/pkg/gradle/lockfile"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/language"
"github.com/aquasecurity/trivy/pkg/fanal/types"

"golang.org/x/xerrors"
)

func init() {
analyzer.RegisterAnalyzer(&gradleLockAnalyzer{})
}

const (
version = 1
fileNameSuffix = "gradle.lockfile"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see on GitHub, that user have lock files with another names. is it ok?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is suffix of filename.
If I understand correctly - we need to check only this suffix.

return strings.HasSuffix(filepath.Base(filePath), fileNameSuffix)

)

// gradleLockAnalyzer analyzes '*gradle.lockfile'
type gradleLockAnalyzer struct{}

func (a gradleLockAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
p := lockfile.NewParser()
res, err := language.Analyze(types.Gradle, input.FilePath, input.Content, p)
if err != nil {
return nil, xerrors.Errorf("%s parse error: %w", input.FilePath, err)
}
return res, nil
}

func (a gradleLockAnalyzer) Required(_ string, fileInfo os.FileInfo) bool {
return strings.HasSuffix(fileInfo.Name(), fileNameSuffix)
}

func (a gradleLockAnalyzer) Type() analyzer.Type {
return analyzer.TypeGradleLock
}

func (a gradleLockAnalyzer) Version() int {
return version
}