feat(java): support jar/war/ear (#837)

* refactor(server): remove Detect endpoint

* refactor(library): do not use interface

* refactor: add dbtest package

* test: add bolt fixtures

* feat: support jar scanning

* refactor: rename node to npm

* refactor: fix lint issues

* test(maven): remove some tests

* chore(mod): update fanal

* docs: update README

* chore(mod): update trivy-db

* fix(library/drive): add ecosystem

* fix: do not display 0 vulnerabilities

* refactor(table): split method

* Update README.md (#838)

* fix(app): increase the default value of timeout (#842)

* feat(maven): use go-mvn-version

* test(maven): update tests

* fix(scan): skip files and dirs before vulnerability detection

* fix: display log messages only once per type

* docs(README): add file suffixes

* chore(mod): update go-mvn-version

* feat(log): set go-dep-parser logger

* chore(mod): update fanal

* docs: update README

* docs(README): add java source

* test(maven): fix invalid case
This commit is contained in:
Teppei Fukuda
2021-02-14 18:19:42 +02:00
committed by GitHub
parent 3047c524d9
commit c9f22f4e55
43 changed files with 455 additions and 2695 deletions

View File

@@ -103,7 +103,7 @@ See [here](#continuous-integration-ci) for details.
- Detect comprehensive vulnerabilities
- OS packages (Alpine, **Red Hat Universal Base Image**, Red Hat Enterprise Linux, CentOS, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
- **Application dependencies** (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo and NuGet)
- **Application dependencies** (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, and Maven)
- Simple
- Specify only an image name or artifact name
- See [Quick Start](#quick-start) and [Examples](#examples)
@@ -1763,6 +1763,8 @@ Distroless: https://github.com/GoogleContainerTools/distroless
- Cargo.lock
- .NET
- packages.lock.json
- Java
- JAR/WAR/EAR files (*.jar, *.war, and *.ear)
The path of these files does not matter.
@@ -1796,6 +1798,8 @@ Trivy scans a tar image with the following format.
- https://github.com/RustSec/advisory-db
- .NET
- https://github.com/advisories?query=ecosystem%3Anuget
- Java
- https://github.com/advisories?query=ecosystem%3Amaven
# Usage
Trivy has several sub commands, image, fs, repo, client and server.
@@ -1921,7 +1925,7 @@ See [here](docs/air-gap.md)
| Scanner | OS<br>Packages | Application<br>Dependencies | Easy to use | Accuracy | Suitable<br>for CI |
| -------------- | :-------------: | :-------------------------: | :----------: | :---------: | :-----------------: |
| Trivy | ✅ | ✅<br>(5 languages) | ⭐ ⭐ ⭐ | ⭐ ⭐ ⭐ | ⭐ ⭐ ⭐ |
| Trivy | ✅ | ✅<br>(7 languages) | ⭐ ⭐ ⭐ | ⭐ ⭐ ⭐ | ⭐ ⭐ ⭐ |
| Clair | ✅ | × | ⭐ | ⭐ ⭐ | ⭐ ⭐ |
| Anchore Engine | ✅ | ✅<br>(4 languages) | ⭐ ⭐ | ⭐ ⭐ | ⭐ ⭐ ⭐ |
| Quay | ✅ | × | ⭐ ⭐ ⭐ | ⭐ ⭐ | × |

15
go.mod
View File

@@ -4,13 +4,13 @@ go 1.15
require (
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/fanal v0.0.0-20210119051230-28c249da7cfd
github.com/aquasecurity/go-dep-parser v0.0.0-20201028043324-889d4a92b8e0
github.com/aquasecurity/fanal v0.0.0-20210214122859-98d76e2b3b96
github.com/aquasecurity/go-dep-parser v0.0.0-20210214113128-b97635cfd627
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
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492
github.com/aquasecurity/trivy-db v0.0.0-20210105160501-c5bf4e153277
github.com/aquasecurity/trivy-db v0.0.0-20210214043256-acc144af2228
github.com/caarlos0/env/v6 v6.0.0
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cheggaaa/pb/v3 v3.0.3
@@ -30,6 +30,7 @@ require (
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936
github.com/kylelemons/godebug v1.1.0
github.com/masahiro331/go-mvn-version v0.0.0-20210214074851-415aa65db8c0
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a
github.com/open-policy-agent/opa v0.21.1
@@ -37,13 +38,11 @@ require (
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/spf13/afero v1.2.2
github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.6.1
github.com/stretchr/testify v1.7.0
github.com/testcontainers/testcontainers-go v0.3.1
github.com/twitchtv/twirp v5.10.1+incompatible
github.com/urfave/cli/v2 v2.3.0
go.uber.org/atomic v1.5.1 // indirect
go.uber.org/multierr v1.4.0 // indirect
go.uber.org/zap v1.13.0
go.uber.org/zap v1.16.0
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5
golang.org/x/sys v0.0.0-20201006155630-ac719f4daadf // indirect
@@ -51,6 +50,6 @@ require (
google.golang.org/protobuf v1.25.0
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/utils v0.0.0-20201110183641-67b214c5f920
)

34
go.sum
View File

@@ -91,10 +91,10 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30xLN2sUZcMXl50hg+PJCIDdJgIvIbVcKqLJ/ZrtM=
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8=
github.com/aquasecurity/fanal v0.0.0-20210119051230-28c249da7cfd h1:meqa2AA+7K1r/nfNB19K2AP/v8+nemuWeQoTSqZ2R9s=
github.com/aquasecurity/fanal v0.0.0-20210119051230-28c249da7cfd/go.mod h1:kur6SaohYhsjQLzijAdtn+X8rkTtwxawE51WyVCXLKk=
github.com/aquasecurity/go-dep-parser v0.0.0-20201028043324-889d4a92b8e0 h1:cLH3SebzhbJ+jU1GIad8A1N8p7m7OjHhtY6JePISiVc=
github.com/aquasecurity/go-dep-parser v0.0.0-20201028043324-889d4a92b8e0/go.mod h1:X42mTIRhgPalSm81Om2kD+3ydeunbC8TZtZj1bvgRo8=
github.com/aquasecurity/fanal v0.0.0-20210214122859-98d76e2b3b96 h1:5Uk/RmXp+Itbm3fLa0vg1OKBl6Z6BfxDVrJpwETYqWk=
github.com/aquasecurity/fanal v0.0.0-20210214122859-98d76e2b3b96/go.mod h1:8HoL/kipOrDodHh+jzGgO2/iXJoRf6roLP5qPv8Mi90=
github.com/aquasecurity/go-dep-parser v0.0.0-20210214113128-b97635cfd627 h1:ccLbhkZ54xTmI6Q+CyBL8sll+OXIEzX0aDDjmy8pVWQ=
github.com/aquasecurity/go-dep-parser v0.0.0-20210214113128-b97635cfd627/go.mod h1:KHiF3uK6FOE1v27YK+5CWEJ1jd0OvA2Gmk8VFjT3utk=
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-npm-version v0.0.0-20201110091526-0b796d180798 h1:eveqE9ivrt30CJ7dOajOfBavhZ4zPqHcZe/4tKp0alc=
@@ -107,8 +107,8 @@ github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 h1:rcEG5HI
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492/go.mod h1:9Beu8XsUNNfzml7WBf3QmyPToP1wm1Gj/Vc5UJKqTzU=
github.com/aquasecurity/testdocker v0.0.0-20210106133225-0b17fe083674 h1:Xq/HxWFGaB4G/prC6czH/F5woB91GMCCilJxs/5DnDk=
github.com/aquasecurity/testdocker v0.0.0-20210106133225-0b17fe083674/go.mod h1:psfu0MVaiTDLpNxCoNsTeILSKY2EICBwv345f3M+Ffs=
github.com/aquasecurity/trivy-db v0.0.0-20210105160501-c5bf4e153277 h1:lXN72H9uNM1exUArIsN++n7b67PIaqhZON2cVWxwmpg=
github.com/aquasecurity/trivy-db v0.0.0-20210105160501-c5bf4e153277/go.mod h1:N7CWA/vjVw78GWAdCJGhFQVqNGEA4e47a6eIWm+C/Bc=
github.com/aquasecurity/trivy-db v0.0.0-20210214043256-acc144af2228 h1:Hl1eKVUApdGdMUNiSYWekViWccauKxscorOV2bc1cJE=
github.com/aquasecurity/trivy-db v0.0.0-20210214043256-acc144af2228/go.mod h1:N7CWA/vjVw78GWAdCJGhFQVqNGEA4e47a6eIWm+C/Bc=
github.com/aquasecurity/vuln-list-update v0.0.0-20191016075347-3d158c2bf9a2 h1:xbdUfr2KE4THsFx9CFWtWpU91lF+YhgP46moV94nYTA=
github.com/aquasecurity/vuln-list-update v0.0.0-20191016075347-3d158c2bf9a2/go.mod h1:6NhOP0CjZJL27bZZcaHECtzWdwDDm2g6yCY0QgXEGQQ=
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
@@ -429,6 +429,8 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/masahiro331/go-mvn-version v0.0.0-20210214074851-415aa65db8c0 h1:GT77MM4NtCZv3oeOlY+Y7EANZ86/h49oqPytEKTm3f8=
github.com/masahiro331/go-mvn-version v0.0.0-20210214074851-415aa65db8c0/go.mod h1:M5wLEr5YKZ6OcOpiNGO0qPE4cd+xjUbBLlBvJGhZgWQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -584,6 +586,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/testcontainers/testcontainers-go v0.3.1 h1:KZkEKNfnlsipJblzGCz6fmzd+0DzJ3djulYrislG3Zw=
github.com/testcontainers/testcontainers-go v0.3.1/go.mod h1:br7bkzIukhPSIjy07Ma3OuXjjFvl2jm7CDU0LQNsqLw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -624,18 +628,16 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opentelemetry.io/otel v0.14.0 h1:YFBEfjCk9MTjaytCNSUkp9Q8lF7QJezA06T71FbQxLQ=
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM=
go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E=
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -993,8 +995,8 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v0.0.0-20181223230014-1083505acf35/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=

View File

@@ -14,7 +14,6 @@ import (
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/fanal/image"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/aquasecurity/trivy/pkg/detector/ospkg"
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/scanner/local"
@@ -28,9 +27,7 @@ import (
func initializeDockerScanner(ctx context.Context, imageName string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, timeout time.Duration) (scanner.Scanner, func(), error) {
applierApplier := applier.NewApplier(localArtifactCache)
detector := ospkg.Detector{}
driverFactory := library.DriverFactory{}
libraryDetector := library.NewDetector(driverFactory)
localScanner := local.NewScanner(applierApplier, detector, libraryDetector)
localScanner := local.NewScanner(applierApplier, detector)
dockerOption, err := types.GetDockerOption(timeout)
if err != nil {
return scanner.Scanner{}, nil, err
@@ -49,9 +46,7 @@ func initializeDockerScanner(ctx context.Context, imageName string, artifactCach
func initializeArchiveScanner(ctx context.Context, filePath string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache, timeout time.Duration) (scanner.Scanner, error) {
applierApplier := applier.NewApplier(localArtifactCache)
detector := ospkg.Detector{}
driverFactory := library.DriverFactory{}
libraryDetector := library.NewDetector(driverFactory)
localScanner := local.NewScanner(applierApplier, detector, libraryDetector)
localScanner := local.NewScanner(applierApplier, detector)
imageImage, err := image.NewArchiveImage(filePath)
if err != nil {
return scanner.Scanner{}, err
@@ -64,9 +59,7 @@ func initializeArchiveScanner(ctx context.Context, filePath string, artifactCach
func initializeFilesystemScanner(ctx context.Context, dir string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache) (scanner.Scanner, func(), error) {
applierApplier := applier.NewApplier(localArtifactCache)
detector := ospkg.Detector{}
driverFactory := library.DriverFactory{}
libraryDetector := library.NewDetector(driverFactory)
localScanner := local.NewScanner(applierApplier, detector, libraryDetector)
localScanner := local.NewScanner(applierApplier, detector)
artifact := local2.NewArtifact(dir, artifactCache)
scannerScanner := scanner.NewScanner(localScanner, artifact)
return scannerScanner, func() {
@@ -76,9 +69,7 @@ func initializeFilesystemScanner(ctx context.Context, dir string, artifactCache
func initializeRepositoryScanner(ctx context.Context, url string, artifactCache cache.ArtifactCache, localArtifactCache cache.LocalArtifactCache) (scanner.Scanner, func(), error) {
applierApplier := applier.NewApplier(localArtifactCache)
detector := ospkg.Detector{}
driverFactory := library.DriverFactory{}
libraryDetector := library.NewDetector(driverFactory)
localScanner := local.NewScanner(applierApplier, detector, libraryDetector)
localScanner := local.NewScanner(applierApplier, detector)
artifact, cleanup, err := remote.NewArtifact(url, artifactCache)
if err != nil {
return scanner.Scanner{}, nil, err

View File

@@ -8,6 +8,8 @@ import (
"testing"
"time"
rpcScanner "github.com/aquasecurity/trivy/rpc/scanner"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -18,7 +20,6 @@ import (
"github.com/aquasecurity/fanal/types"
"github.com/aquasecurity/trivy/pkg/cache"
rpcCache "github.com/aquasecurity/trivy/rpc/cache"
"github.com/aquasecurity/trivy/rpc/detector"
)
type mockCacheServer struct {
@@ -53,7 +54,7 @@ func (s *mockCacheServer) MissingBlobs(_ context.Context, in *rpcCache.MissingBl
func withToken(base http.Handler, token, tokenHeader string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if token != "" && token != r.Header.Get(tokenHeader) {
detector.WriteError(w, twirp.NewError(twirp.Unauthenticated, "invalid token"))
rpcScanner.WriteError(w, twirp.NewError(twirp.Unauthenticated, "invalid token"))
return
}
base.ServeHTTP(w, r)

34
pkg/dbtest/db.go Normal file
View File

@@ -0,0 +1,34 @@
package dbtest
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
fixtures "github.com/aquasecurity/bolt-fixtures"
"github.com/aquasecurity/trivy-db/pkg/db"
)
// InitDB initializes testing database.
func InitDB(t *testing.T, fixtureFiles []string) string {
// Create a temp dir
dir := t.TempDir()
dbPath := db.Path(dir)
dbDir := filepath.Dir(dbPath)
err := os.MkdirAll(dbDir, 0700)
require.NoError(t, err)
// Load testdata into BoltDB
loader, err := fixtures.New(dbPath, fixtureFiles)
require.NoError(t, err)
require.NoError(t, loader.Load())
require.NoError(t, loader.Close())
// Initialize DB
require.NoError(t, db.Init(dir))
return dir
}

View File

@@ -1,7 +1,6 @@
package library_test
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
@@ -9,11 +8,11 @@ import (
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/aquasecurity/trivy/pkg/detector/library/bundler"
"github.com/aquasecurity/trivy/pkg/detector/library/comparer"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestAdvisory_DetectVulnerabilities(t *testing.T) {
@@ -98,8 +97,7 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Initialize DB
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
adv := library.NewAdvisory(tt.ecosystem, tt.comparer)

View File

@@ -1,16 +1,16 @@
package bundler_test
import (
"os"
"testing"
"github.com/aquasecurity/trivy/pkg/detector/library/bundler"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestAdvisory_DetectVulnerabilities(t *testing.T) {
@@ -65,8 +65,8 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
log.InitLogger(false, true)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
a := bundler.NewAdvisory()
got, err := a.DetectVulnerabilities(tt.args.pkgName, tt.args.pkgVer)

View File

@@ -1,17 +1,16 @@
package cargo_test
import (
"os"
"testing"
"github.com/aquasecurity/trivy/pkg/detector/library/cargo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/cargo"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestAdvisory_DetectVulnerabilities(t *testing.T) {
@@ -81,8 +80,8 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
log.InitLogger(false, true)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
a := cargo.NewAdvisory()
got, err := a.DetectVulnerabilities(tt.args.pkgName, tt.args.pkgVer)

View File

@@ -1,17 +1,16 @@
package composer_test
import (
"os"
"testing"
"github.com/aquasecurity/trivy/pkg/detector/library/composer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/composer"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestAdvisory_DetectVulnerabilities(t *testing.T) {
@@ -65,8 +64,8 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
log.InitLogger(false, true)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
a := composer.NewAdvisory()
got, err := a.DetectVulnerabilities(tt.args.pkgName, tt.args.pkgVer)

View File

@@ -1,44 +1,15 @@
package library
import (
"path/filepath"
"time"
"github.com/google/wire"
"golang.org/x/xerrors"
ftypes "github.com/aquasecurity/fanal/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
)
// SuperSet binds the dependencies for library scan
var SuperSet = wire.NewSet(
wire.Struct(new(DriverFactory)),
wire.Bind(new(Factory), new(DriverFactory)),
NewDetector,
wire.Bind(new(Operation), new(Detector)),
)
// Operation defines library scan operations
type Operation interface {
Detect(imageName string, filePath string, created time.Time, pkgs []ftypes.LibraryInfo) (vulns []types.DetectedVulnerability, err error)
}
// Detector implements driverFactory
type Detector struct {
driverFactory Factory
}
// NewDetector is the factory method for detector
func NewDetector(factory Factory) Detector {
return Detector{driverFactory: factory}
}
// Detect scans and returns vulnerabilities of library
func (d Detector) Detect(_, filePath string, _ time.Time, pkgs []ftypes.LibraryInfo) ([]types.DetectedVulnerability, error) {
log.Logger.Debugf("Detecting library vulnerabilities, path: %s", filePath)
driver, err := d.driverFactory.NewDriver(filepath.Base(filePath))
func Detect(libType string, pkgs []ftypes.LibraryInfo) ([]types.DetectedVulnerability, error) {
driver, err := NewDriver(libType)
if err != nil {
return nil, xerrors.Errorf("failed to new driver: %w", err)
}
@@ -52,7 +23,6 @@ func (d Detector) Detect(_, filePath string, _ time.Time, pkgs []ftypes.LibraryI
}
func detect(driver Driver, libs []ftypes.LibraryInfo) ([]types.DetectedVulnerability, error) {
log.Logger.Infof("Detecting %s vulnerabilities...", driver.Type())
var vulnerabilities []types.DetectedVulnerability
for _, lib := range libs {
vulns, err := driver.Detect(lib.Library.Name, lib.Library.Version)

View File

@@ -1,10 +1,9 @@
package library
import (
"fmt"
"golang.org/x/xerrors"
"github.com/aquasecurity/fanal/analyzer/library"
ecosystem "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ghsa"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability"
"github.com/aquasecurity/trivy/pkg/detector/library/bundler"
@@ -12,41 +11,36 @@ import (
"github.com/aquasecurity/trivy/pkg/detector/library/comparer"
"github.com/aquasecurity/trivy/pkg/detector/library/composer"
"github.com/aquasecurity/trivy/pkg/detector/library/ghsa"
"github.com/aquasecurity/trivy/pkg/detector/library/node"
"github.com/aquasecurity/trivy/pkg/detector/library/maven"
"github.com/aquasecurity/trivy/pkg/detector/library/npm"
"github.com/aquasecurity/trivy/pkg/detector/library/python"
"github.com/aquasecurity/trivy/pkg/types"
)
// Factory defines library operations
type Factory interface {
NewDriver(filename string) (Driver, error)
}
type advisory interface {
DetectVulnerabilities(string, string) ([]types.DetectedVulnerability, error)
}
// DriverFactory implements Factory
type DriverFactory struct{}
// NewDriver factory method for driver
func (d DriverFactory) NewDriver(filename string) (Driver, error) {
// NewDriver returns a driver according to the library type
func NewDriver(libType string) (Driver, error) {
var driver Driver
switch filename {
case "Gemfile.lock":
switch libType {
case library.Bundler:
driver = newRubyGemsDriver()
case "Cargo.lock":
case library.Cargo:
driver = newCargoDriver()
case "composer.lock":
case library.Composer:
driver = newComposerDriver()
case "package-lock.json", "yarn.lock":
case library.Npm, library.Yarn:
driver = newNpmDriver()
case "Pipfile.lock", "poetry.lock":
case library.Pipenv, library.Poetry:
driver = newPipDriver()
case "packages.lock.json":
case library.NuGet:
driver = newNugetDriver()
case library.Jar:
driver = newMavenDriver()
default:
return Driver{}, xerrors.New(fmt.Sprintf("unsupport filename %s", filename))
return Driver{}, xerrors.Errorf("unsupported type %s", libType)
}
return driver, nil
}
@@ -57,17 +51,17 @@ type Driver struct {
advisories []advisory
}
// NewDriver is the factory method from drier
func NewDriver(advisories ...advisory) Driver {
return Driver{advisories: advisories}
// Aggregate aggregates drivers
func Aggregate(ecosystem string, advisories ...advisory) Driver {
return Driver{ecosystem: ecosystem, advisories: advisories}
}
// Detect scans and returns vulnerabilities
func (d *Driver) Detect(pkgName string, pkgVer string) ([]types.DetectedVulnerability, error) {
var detectedVulnerabilities []types.DetectedVulnerability
uniqVulnIDMap := make(map[string]struct{})
for _, d := range d.advisories {
vulns, err := d.DetectVulnerabilities(pkgName, pkgVer)
for _, adv := range d.advisories {
vulns, err := adv.DetectVulnerabilities(pkgName, pkgVer)
if err != nil {
return nil, xerrors.Errorf("failed to detect vulnerabilities: %w", err)
}
@@ -90,34 +84,41 @@ func (d *Driver) Type() string {
func newRubyGemsDriver() Driver {
c := bundler.RubyGemsComparer{}
return NewDriver(ghsa.NewAdvisory(ecosystem.Rubygems, c), bundler.NewAdvisory(),
return Aggregate(vulnerability.RubyGems, ghsa.NewAdvisory(ecosystem.Rubygems, c), bundler.NewAdvisory(),
NewAdvisory(vulnerability.RubyGems, c))
}
func newComposerDriver() Driver {
c := comparer.GenericComparer{}
return NewDriver(
ghsa.NewAdvisory(ecosystem.Composer, c), composer.NewAdvisory(),
return Aggregate(vulnerability.Composer, ghsa.NewAdvisory(ecosystem.Composer, c), composer.NewAdvisory(),
NewAdvisory(vulnerability.Composer, c))
}
func newCargoDriver() Driver {
return NewDriver(cargo.NewAdvisory(), NewAdvisory(vulnerability.Cargo, comparer.GenericComparer{}))
return Aggregate(vulnerability.Cargo, cargo.NewAdvisory(),
NewAdvisory(vulnerability.Cargo, comparer.GenericComparer{}))
}
func newNpmDriver() Driver {
c := node.NpmComparer{}
return NewDriver(ghsa.NewAdvisory(ecosystem.Npm, c), node.NewAdvisory(),
NewAdvisory(vulnerability.Npm, c))
c := npm.Comparer{}
return Aggregate(vulnerability.Npm, ghsa.NewAdvisory(ecosystem.Npm, c),
npm.NewAdvisory(), NewAdvisory(vulnerability.Npm, c))
}
func newPipDriver() Driver {
c := comparer.GenericComparer{}
return NewDriver(ghsa.NewAdvisory(ecosystem.Pip, c), python.NewAdvisory(),
NewAdvisory(vulnerability.Pip, c))
return Aggregate(vulnerability.Pip, ghsa.NewAdvisory(ecosystem.Pip, c),
python.NewAdvisory(), NewAdvisory(vulnerability.Pip, c))
}
func newNugetDriver() Driver {
c := comparer.GenericComparer{}
return NewDriver(ghsa.NewAdvisory(ecosystem.Nuget, c), NewAdvisory(vulnerability.NuGet, c))
return Aggregate(vulnerability.NuGet, ghsa.NewAdvisory(ecosystem.Nuget, c),
NewAdvisory(vulnerability.NuGet, c))
}
func newMavenDriver() Driver {
c := maven.Comparer{}
return Aggregate(vulnerability.Maven, ghsa.NewAdvisory(ecosystem.Maven, c),
NewAdvisory(vulnerability.Maven, c))
}

View File

@@ -1,22 +1,19 @@
package library_test
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
lib "github.com/aquasecurity/fanal/analyzer/library"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestDriver_Detect(t *testing.T) {
type fields struct {
fileName string
}
type args struct {
pkgName string
pkgVer string
@@ -24,7 +21,7 @@ func TestDriver_Detect(t *testing.T) {
tests := []struct {
name string
fixtures []string
fields fields
libType string
args args
want []types.DetectedVulnerability
wantErr string
@@ -32,7 +29,7 @@ func TestDriver_Detect(t *testing.T) {
{
name: "happy path",
fixtures: []string{"testdata/fixtures/php.yaml"},
fields: fields{fileName: "composer.lock"},
libType: lib.Composer,
args: args{
pkgName: "symfony/symfony",
pkgVer: "4.2.6",
@@ -49,7 +46,7 @@ func TestDriver_Detect(t *testing.T) {
{
name: "non-prefix buckets",
fixtures: []string{"testdata/fixtures/php-without-prefix.yaml"},
fields: fields{fileName: "composer.lock"},
libType: lib.Composer,
args: args{
pkgName: "symfony/symfony",
pkgVer: "4.2.6",
@@ -66,7 +63,7 @@ func TestDriver_Detect(t *testing.T) {
{
name: "no patched versions in the advisory",
fixtures: []string{"testdata/fixtures/php.yaml"},
fields: fields{fileName: "composer.lock"},
libType: lib.Composer,
args: args{
pkgName: "symfony/symfony",
pkgVer: "4.4.6",
@@ -83,7 +80,7 @@ func TestDriver_Detect(t *testing.T) {
{
name: "no vulnerable versions in the advisory",
fixtures: []string{"testdata/fixtures/ruby.yaml"},
fields: fields{fileName: "Gemfile.lock"},
libType: lib.Bundler,
args: args{
pkgName: "activesupport",
pkgVer: "4.1.1",
@@ -100,7 +97,7 @@ func TestDriver_Detect(t *testing.T) {
{
name: "no vulnerability",
fixtures: []string{"testdata/fixtures/php.yaml"},
fields: fields{fileName: "composer.lock"},
libType: lib.Composer,
args: args{
pkgName: "symfony/symfony",
pkgVer: "4.4.7",
@@ -110,12 +107,10 @@ func TestDriver_Detect(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Initialize DB
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
factory := library.DriverFactory{}
driver, err := factory.NewDriver(tt.fields.fileName)
driver, err := library.NewDriver(tt.libType)
require.NoError(t, err)
got, err := driver.Detect(tt.args.pkgName, tt.args.pkgVer)

View File

@@ -1,18 +1,18 @@
package ghsa_test
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db"
ghsaSrc "github.com/aquasecurity/trivy-db/pkg/vulnsrc/ghsa"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/comparer"
"github.com/aquasecurity/trivy/pkg/detector/library/ghsa"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestAdvisory_DetectVulnerabilities(t *testing.T) {
@@ -103,8 +103,8 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
log.InitLogger(false, true)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
a := ghsa.NewAdvisory(tt.fields.ecosystem, tt.fields.comparer)
got, err := a.DetectVulnerabilities(tt.args.pkgName, tt.args.pkgVer)

View File

@@ -0,0 +1,33 @@
package maven
import (
"golang.org/x/xerrors"
version "github.com/masahiro331/go-mvn-version"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/detector/library/comparer"
)
// Comparer represents a comparer for maven
type Comparer struct{}
// IsVulnerable checks if the package version is vulnerable to the advisory.
func (n Comparer) IsVulnerable(ver string, advisory dbTypes.Advisory) bool {
return comparer.IsVulnerable(ver, advisory, n.matchVersion)
}
// matchVersion checks if the package version satisfies the given constraint.
func (n Comparer) matchVersion(currentVersion, constraint string) (bool, error) {
v, err := version.NewVersion(currentVersion)
if err != nil {
return false, xerrors.Errorf("maven version error (%s): %s", currentVersion, err)
}
c, err := version.NewConstraints(constraint)
if err != nil {
return false, xerrors.Errorf("maven constraint error (%s): %s", constraint, err)
}
return c.Check(v), nil
}

View File

@@ -0,0 +1,87 @@
package maven_test
import (
"testing"
"github.com/aquasecurity/trivy/pkg/detector/library/maven"
"github.com/stretchr/testify/assert"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/log"
)
func TestComparer_IsVulnerable(t *testing.T) {
type args struct {
currentVersion string
advisory dbTypes.Advisory
}
tests := []struct {
name string
args args
want bool
}{
{
name: "happy path",
args: args{
currentVersion: "1.0.0",
advisory: dbTypes.Advisory{
VulnerableVersions: []string{"<=1.0"},
PatchedVersions: []string{">=1.1"},
},
},
want: true,
},
{
name: "final release",
args: args{
currentVersion: "1.2.3.final",
advisory: dbTypes.Advisory{
VulnerableVersions: []string{"<1.2.3"},
PatchedVersions: []string{"1.2.3"},
},
},
want: false,
},
{
name: "pre-release",
args: args{
currentVersion: "1.2.3-a1",
advisory: dbTypes.Advisory{
VulnerableVersions: []string{"<1.2.3"},
PatchedVersions: []string{">=1.2.3"},
},
},
want: true,
},
{
name: "multiple constraints",
args: args{
currentVersion: "2.0.0",
advisory: dbTypes.Advisory{
VulnerableVersions: []string{">=1.7.0 <1.7.16", ">=1.8.0 <1.8.8", ">=2.0.0 <2.0.8", ">=3.0.0-beta.1 <3.0.0-beta.7"},
PatchedVersions: []string{">=3.0.0-beta.7", ">=2.0.8 <3.0.0-beta.1", ">=1.8.8 <2.0.0", ">=1.7.16 <1.8.0"},
},
},
want: true,
},
{
name: "invalid constraint",
args: args{
currentVersion: "1.2.3",
advisory: dbTypes.Advisory{
VulnerableVersions: []string{`<1.0\.0`},
},
},
want: false,
},
}
log.InitLogger(false, false)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := maven.Comparer{}
got := c.IsVulnerable(tt.args.currentVersion, tt.args.advisory)
assert.Equal(t, tt.want, got)
})
}
}

View File

@@ -1,4 +1,4 @@
package node
package npm
import (
"strings"
@@ -12,7 +12,7 @@ import (
// Advisory encapsulate Node vulnerability source
type Advisory struct {
comparer NpmComparer
comparer Comparer
vs node.VulnSrc
}
@@ -20,7 +20,7 @@ type Advisory struct {
func NewAdvisory() *Advisory {
return &Advisory{
vs: node.NewVulnSrc(),
comparer: NpmComparer{},
comparer: Comparer{},
}
}

View File

@@ -1,16 +1,16 @@
package node_test
package npm_test
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy/pkg/detector/library/node"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/npm"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestAdvisory_DetectVulnerabilities(t *testing.T) {
@@ -72,10 +72,10 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
log.InitLogger(false, true)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
a := node.NewAdvisory()
a := npm.NewAdvisory()
got, err := a.DetectVulnerabilities(tt.args.pkgName, tt.args.pkgVer)
if tt.wantErr != "" {
require.NotNil(t, err)

View File

@@ -1,4 +1,4 @@
package node
package npm
import (
"golang.org/x/xerrors"
@@ -8,16 +8,16 @@ import (
"github.com/aquasecurity/trivy/pkg/detector/library/comparer"
)
// NpmComparer represents a comparer for npm
type NpmComparer struct{}
// Comparer represents a comparer for npm
type Comparer struct{}
// IsVulnerable checks if the package version is vulnerable to the advisory.
func (n NpmComparer) IsVulnerable(ver string, advisory dbTypes.Advisory) bool {
func (n Comparer) IsVulnerable(ver string, advisory dbTypes.Advisory) bool {
return comparer.IsVulnerable(ver, advisory, n.matchVersion)
}
// matchVersion checks if the package version satisfies the given constraint.
func (n NpmComparer) matchVersion(currentVersion, constraint string) (bool, error) {
func (n Comparer) matchVersion(currentVersion, constraint string) (bool, error) {
v, err := npm.NewVersion(currentVersion)
if err != nil {
return false, xerrors.Errorf("npm version error (%s): %s", currentVersion, err)

View File

@@ -1,4 +1,4 @@
package node_test
package npm_test
import (
"testing"
@@ -6,7 +6,7 @@ import (
"github.com/stretchr/testify/assert"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/detector/library/node"
"github.com/aquasecurity/trivy/pkg/detector/library/npm"
"github.com/aquasecurity/trivy/pkg/log"
)
@@ -132,7 +132,7 @@ func TestNpmComparer_IsVulnerable(t *testing.T) {
log.InitLogger(false, false)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := node.NpmComparer{}
c := npm.Comparer{}
got := c.IsVulnerable(tt.args.currentVersion, tt.args.advisory)
assert.Equal(t, tt.want, got)
})

View File

@@ -1,16 +1,16 @@
package python_test
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/detector/library/python"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
)
func TestAdvisory_DetectVulnerabilities(t *testing.T) {
@@ -65,8 +65,8 @@ func TestAdvisory_DetectVulnerabilities(t *testing.T) {
log.InitLogger(false, true)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
a := python.NewAdvisory()
got, err := a.DetectVulnerabilities(tt.args.pkgName, tt.args.pkgVer)

View File

@@ -5,17 +5,17 @@ import (
"testing"
"time"
ftypes "github.com/aquasecurity/fanal/types"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
oracleoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/oracle-oval"
"github.com/aquasecurity/trivy/pkg/log"
"k8s.io/utils/clock"
clocktesting "k8s.io/utils/clock/testing"
ftypes "github.com/aquasecurity/fanal/types"
"github.com/aquasecurity/trivy-db/pkg/db"
oracleoval "github.com/aquasecurity/trivy-db/pkg/vulnsrc/oracle-oval"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
)
func TestMain(m *testing.M) {
@@ -209,8 +209,8 @@ func TestScanner_Detect(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := utils.InitTestDB(t, tt.fixtures)
defer os.RemoveAll(dir)
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
s := NewScanner()
got, err := s.Detect(tt.args.osVer, tt.args.pkgs)

View File

@@ -6,6 +6,8 @@ import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"golang.org/x/xerrors"
"github.com/aquasecurity/go-dep-parser/pkg/log"
)
var (
@@ -19,8 +21,12 @@ func InitLogger(debug, disable bool) (err error) {
debugOption = debug
Logger, err = NewLogger(debug, disable)
if err != nil {
return xerrors.Errorf("error in new logger: %w", err)
return xerrors.Errorf("failed to initialize a logger: %w", err)
}
// Set logger for go-dep-parser
log.SetLogger(Logger)
return nil
}

View File

@@ -74,13 +74,14 @@ type TableWriter struct {
// Write writes the result on standard output
func (tw TableWriter) Write(results Results) error {
for _, result := range results {
if len(result.Vulnerabilities) == 0 {
continue
}
tw.write(result)
}
return nil
}
// nolint: gocyclo
// TODO: refactror and fix cyclometic complexity
func (tw TableWriter) write(result Result) {
table := tablewriter.NewWriter(tw.Output)
header := []string{"Library", "Vulnerability ID", "Severity", "Installed Version", "Fixed Version"}
@@ -88,38 +89,7 @@ func (tw TableWriter) write(result Result) {
header = append(header, "Title")
}
table.SetHeader(header)
severityCount := map[string]int{}
for _, v := range result.Vulnerabilities {
severityCount[v.Severity]++
title := v.Title
if title == "" {
title = v.Description
}
splittedTitle := strings.Split(title, " ")
if len(splittedTitle) >= 12 {
title = strings.Join(splittedTitle[:12], " ") + "..."
}
if len(v.PrimaryURL) > 0 {
r := strings.NewReplacer("https://", "", "http://", "")
title = fmt.Sprintf("%s -->%s", title, r.Replace(v.PrimaryURL))
}
var row []string
if tw.Output == os.Stdout {
row = []string{v.PkgName, v.VulnerabilityID, dbTypes.ColorizeSeverity(v.Severity),
v.InstalledVersion, v.FixedVersion}
} else {
row = []string{v.PkgName, v.VulnerabilityID, v.Severity, v.InstalledVersion, v.FixedVersion}
}
if !tw.Light {
row = append(row, strings.TrimSpace(title))
}
table.Append(row)
}
severityCount := tw.setRows(table, result.Vulnerabilities)
var results []string
@@ -150,6 +120,41 @@ func (tw TableWriter) write(result Result) {
return
}
func (tw TableWriter) setRows(table *tablewriter.Table, vulns []types.DetectedVulnerability) map[string]int {
severityCount := map[string]int{}
for _, v := range vulns {
severityCount[v.Severity]++
title := v.Title
if title == "" {
title = v.Description
}
splitTitle := strings.Split(title, " ")
if len(splitTitle) >= 12 {
title = strings.Join(splitTitle[:12], " ") + "..."
}
if len(v.PrimaryURL) > 0 {
r := strings.NewReplacer("https://", "", "http://", "")
title = fmt.Sprintf("%s -->%s", title, r.Replace(v.PrimaryURL))
}
var row []string
if tw.Output == os.Stdout {
row = []string{v.PkgName, v.VulnerabilityID, dbTypes.ColorizeSeverity(v.Severity),
v.InstalledVersion, v.FixedVersion}
} else {
row = []string{v.PkgName, v.VulnerabilityID, v.Severity, v.InstalledVersion, v.FixedVersion}
}
if !tw.Light {
row = append(row, strings.TrimSpace(title))
}
table.Append(row)
}
return severityCount
}
// JSONWriter implements result Writer
type JSONWriter struct {
Output io.Writer

View File

@@ -4,8 +4,6 @@ package server
import (
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/trivy/pkg/rpc/server/library"
"github.com/aquasecurity/trivy/pkg/rpc/server/ospkg"
"github.com/google/wire"
)
@@ -14,16 +12,6 @@ func initializeScanServer(localArtifactCache cache.LocalArtifactCache) *ScanServ
return &ScanServer{}
}
func initializeOspkgServer() *ospkg.Server {
wire.Build(ospkg.SuperSet)
return &ospkg.Server{}
}
func initializeLibServer() *library.Server {
wire.Build(library.SuperSet)
return &library.Server{}
}
func initializeDBWorker(cacheDir string, quiet bool) dbWorker {
wire.Build(DBWorkerSuperSet)
return dbWorker{}

View File

@@ -1,47 +0,0 @@
package library
import (
"context"
"time"
"github.com/google/wire"
"golang.org/x/xerrors"
detector "github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/rpc"
"github.com/aquasecurity/trivy/pkg/vulnerability"
proto "github.com/aquasecurity/trivy/rpc/detector"
)
// SuperSet binds the dependencies for library RPC server
var SuperSet = wire.NewSet(
detector.SuperSet,
vulnerability.SuperSet,
NewServer,
)
// Server is for backward compatibility
type Server struct {
detector detector.Operation
vulnClient vulnerability.Operation
}
// NewServer is the facotry method for Server
func NewServer(detector detector.Operation, vulnClient vulnerability.Operation) *Server {
return &Server{detector: detector, vulnClient: vulnClient}
}
// Detect is for backward compatibility
func (s *Server) Detect(_ context.Context, req *proto.LibDetectRequest) (res *proto.DetectResponse, err error) {
vulns, err := s.detector.Detect("", req.FilePath, time.Time{}, rpc.ConvertFromRPCLibraries(req.Libraries))
if err != nil {
err = xerrors.Errorf("failed to detect library vulnerabilities: %w", err)
log.Logger.Error(err)
return nil, err
}
s.vulnClient.FillInfo(vulns, "")
return &proto.DetectResponse{Vulnerabilities: rpc.ConvertToRPCVulns(vulns)}, nil
}

View File

@@ -1,187 +0,0 @@
package library
import (
"context"
"os"
"testing"
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"
ftypes "github.com/aquasecurity/fanal/types"
ptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/utils"
"github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/vulnerability"
"github.com/aquasecurity/trivy/rpc/common"
proto "github.com/aquasecurity/trivy/rpc/detector"
)
func TestMain(m *testing.M) {
log.InitLogger(false, false)
code := m.Run()
os.Exit(code)
}
func TestServer_Detect(t *testing.T) {
type args struct {
req *proto.LibDetectRequest
}
tests := []struct {
name string
args args
detectExpectation library.OperationDetectExpectation
fillInfoExpectation vulnerability.OperationFillInfoExpectation
wantRes *proto.DetectResponse
wantErr string
}{
{
name: "happy path",
args: args{
req: &proto.LibDetectRequest{
ImageName: "alpine:3.10",
FilePath: "app/Pipfile.lock",
Libraries: []*common.Library{
{Name: "django", Version: "3.0.0"},
},
},
},
detectExpectation: library.OperationDetectExpectation{
Args: library.OperationDetectArgs{
FilePath: "app/Pipfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: ptypes.Library{Name: "django", Version: "3.0.0"},
},
},
},
Returns: library.OperationDetectReturns{
Vulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
PkgName: "test",
InstalledVersion: "1",
FixedVersion: "2",
Vulnerability: dbTypes.Vulnerability{
Title: "title",
Description: "description",
Severity: "MEDIUM",
References: []string{"http://example.com"},
LastModifiedDate: utils.MustTimeParse("2020-01-01T01:01:00Z"),
PublishedDate: utils.MustTimeParse("2001-01-01T01:01:00Z"),
CweIDs: []string{"CWE-78"},
},
Layer: ftypes.Layer{
Digest: "sha256:154ad0735c360b212b167f424d33a62305770a1fcfb6363882f5c436cfbd9812",
DiffID: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079",
},
},
},
},
},
fillInfoExpectation: vulnerability.OperationFillInfoExpectation{
Args: vulnerability.OperationFillInfoArgs{
Vulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
PkgName: "test",
InstalledVersion: "1",
FixedVersion: "2",
Vulnerability: dbTypes.Vulnerability{
Title: "title",
Description: "description",
Severity: "MEDIUM",
References: []string{"http://example.com"},
LastModifiedDate: utils.MustTimeParse("2020-01-01T01:01:00Z"),
PublishedDate: utils.MustTimeParse("2001-01-01T01:01:00Z"),
CweIDs: []string{"CWE-78"},
},
Layer: ftypes.Layer{
Digest: "sha256:154ad0735c360b212b167f424d33a62305770a1fcfb6363882f5c436cfbd9812",
DiffID: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079",
},
},
},
},
},
wantRes: &proto.DetectResponse{
Vulnerabilities: []*common.Vulnerability{
{
VulnerabilityId: "CVE-2019-0001",
PkgName: "test",
InstalledVersion: "1",
FixedVersion: "2",
Title: "title",
Description: "description",
Severity: common.Severity_MEDIUM,
Cvss: make(map[string]*common.CVSS),
References: []string{"http://example.com"},
LastModifiedDate: &timestamp.Timestamp{
Seconds: 1577840460,
},
PublishedDate: &timestamp.Timestamp{
Seconds: 978310860,
},
CweIds: []string{"CWE-78"},
Layer: &common.Layer{
Digest: "sha256:154ad0735c360b212b167f424d33a62305770a1fcfb6363882f5c436cfbd9812",
DiffId: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079",
},
},
},
},
},
{
name: "Detect returns an error",
args: args{
req: &proto.LibDetectRequest{
ImageName: "alpine:3.10",
FilePath: "app/Pipfile.lock",
Libraries: []*common.Library{
{Name: "django", Version: "3.0.0"},
},
},
},
detectExpectation: library.OperationDetectExpectation{
Args: library.OperationDetectArgs{
FilePath: "app/Pipfile.lock",
Pkgs: []ftypes.LibraryInfo{
{Library: ptypes.Library{Name: "django", Version: "3.0.0"}},
},
},
Returns: library.OperationDetectReturns{
Err: xerrors.New("error"),
},
},
wantErr: "failed to detect library vulnerabilities",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockDetector := new(library.MockOperation)
mockDetector.ApplyDetectExpectation(tt.detectExpectation)
mockVulnClient := new(vulnerability.MockOperation)
mockVulnClient.ApplyFillInfoExpectation(tt.fillInfoExpectation)
s := NewServer(mockDetector, mockVulnClient)
ctx := context.TODO()
gotRes, err := s.Detect(ctx, tt.args.req)
if tt.wantErr != "" {
require.NotNil(t, err, tt.name)
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
return
} else {
assert.NoError(t, err, tt.name)
}
assert.Equal(t, tt.wantRes, gotRes, tt.name)
mockDetector.AssertExpectations(t)
mockVulnClient.AssertExpectations(t)
})
}
}

View File

@@ -19,8 +19,6 @@ import (
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/utils"
rpcCache "github.com/aquasecurity/trivy/rpc/cache"
"github.com/aquasecurity/trivy/rpc/detector"
rpcDetector "github.com/aquasecurity/trivy/rpc/detector"
rpcScanner "github.com/aquasecurity/trivy/rpc/scanner"
)
@@ -75,14 +73,6 @@ func newServeMux(serverCache cache.Cache, dbUpdateWg, requestWg *sync.WaitGroup,
layerHandler := rpcCache.NewCacheServer(NewCacheServer(serverCache), nil)
mux.Handle(rpcCache.CachePathPrefix, withToken(withWaitGroup(layerHandler), token, tokenHeader))
// osHandler is for backward compatibility
osHandler := rpcDetector.NewOSDetectorServer(initializeOspkgServer(), nil)
mux.Handle(rpcDetector.OSDetectorPathPrefix, withToken(withWaitGroup(osHandler), token, tokenHeader))
// libHandler is for backward compatibility
libHandler := rpcDetector.NewLibDetectorServer(initializeLibServer(), nil)
mux.Handle(rpcDetector.LibDetectorPathPrefix, withToken(withWaitGroup(libHandler), token, tokenHeader))
mux.HandleFunc("/healthz", func(rw http.ResponseWriter, r *http.Request) {
if _, err := rw.Write([]byte("ok")); err != nil {
log.Logger.Errorf("health check error: %s", err)
@@ -95,7 +85,7 @@ func newServeMux(serverCache cache.Cache, dbUpdateWg, requestWg *sync.WaitGroup,
func withToken(base http.Handler, token, tokenHeader string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if token != "" && token != r.Header.Get(tokenHeader) {
detector.WriteError(w, twirp.NewError(twirp.Unauthenticated, "invalid token"))
rpcScanner.WriteError(w, twirp.NewError(twirp.Unauthenticated, "invalid token"))
return
}
base.ServeHTTP(w, r)

View File

@@ -1,47 +0,0 @@
package ospkg
import (
"context"
"time"
"github.com/google/wire"
"golang.org/x/xerrors"
detector "github.com/aquasecurity/trivy/pkg/detector/ospkg"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/rpc"
"github.com/aquasecurity/trivy/pkg/vulnerability"
proto "github.com/aquasecurity/trivy/rpc/detector"
)
// SuperSet binds dependencies for RPC server
var SuperSet = wire.NewSet(
detector.SuperSet,
vulnerability.SuperSet,
NewServer,
)
// Server is for backward compatibility
type Server struct {
detector detector.Operation
vulnClient vulnerability.Operation
}
// NewServer is the factory method to return Server
func NewServer(detector detector.Operation, vulnClient vulnerability.Operation) *Server {
return &Server{detector: detector, vulnClient: vulnClient}
}
// Detect is for backward compatibility
func (s *Server) Detect(_ context.Context, req *proto.OSDetectRequest) (res *proto.DetectResponse, err error) {
vulns, eosl, err := s.detector.Detect("", req.OsFamily, req.OsName, time.Time{}, rpc.ConvertFromRPCPkgs(req.Packages))
if err != nil {
err = xerrors.Errorf("failed to detect vulnerabilities of OS packages: %w", err)
log.Logger.Error(err)
return nil, err
}
s.vulnClient.FillInfo(vulns, "")
return &proto.DetectResponse{Vulnerabilities: rpc.ConvertToRPCVulns(vulns), Eosl: eosl}, nil
}

View File

@@ -1,167 +0,0 @@
package ospkg
import (
"context"
"os"
"testing"
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"
ftypes "github.com/aquasecurity/fanal/types"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/utils"
"github.com/aquasecurity/trivy/pkg/detector/ospkg"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/vulnerability"
"github.com/aquasecurity/trivy/rpc/common"
proto "github.com/aquasecurity/trivy/rpc/detector"
)
func TestMain(m *testing.M) {
_ = log.InitLogger(false, false)
code := m.Run()
os.Exit(code)
}
func TestServer_Detect(t *testing.T) {
type args struct {
req *proto.OSDetectRequest
}
tests := []struct {
name string
args args
detectExpectation ospkg.DetectExpectation
fillInfoExpectation vulnerability.OperationFillInfoExpectation
wantRes *proto.DetectResponse
wantErr string
}{
{
name: "happy path",
args: args{
req: &proto.OSDetectRequest{
OsFamily: "alpine",
OsName: "3.10.2",
Packages: []*common.Package{
{Name: "musl", Version: "1.1.22-r3"},
},
},
},
detectExpectation: ospkg.DetectExpectation{
Args: ospkg.DetectInput{
OSFamily: "alpine",
OSName: "3.10.2",
Pkgs: []ftypes.Package{
{Name: "musl", Version: "1.1.22-r3"},
},
},
ReturnArgs: ospkg.DetectOutput{
Eosl: false,
Vulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
PkgName: "musl",
Vulnerability: dbTypes.Vulnerability{
Severity: "HIGH",
LastModifiedDate: utils.MustTimeParse("2020-01-01T01:01:00Z"),
PublishedDate: utils.MustTimeParse("2001-01-01T01:01:00Z"),
},
Layer: ftypes.Layer{
Digest: "sha256:154ad0735c360b212b167f424d33a62305770a1fcfb6363882f5c436cfbd9812",
DiffID: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079",
},
},
},
},
},
fillInfoExpectation: vulnerability.OperationFillInfoExpectation{
Args: vulnerability.OperationFillInfoArgs{
Vulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2019-0001",
PkgName: "musl",
Vulnerability: dbTypes.Vulnerability{
Severity: "HIGH",
LastModifiedDate: utils.MustTimeParse("2020-01-01T01:01:00Z"),
PublishedDate: utils.MustTimeParse("2001-01-01T01:01:00Z"),
},
Layer: ftypes.Layer{
Digest: "sha256:154ad0735c360b212b167f424d33a62305770a1fcfb6363882f5c436cfbd9812",
DiffID: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079",
},
},
},
},
},
wantRes: &proto.DetectResponse{
Vulnerabilities: []*common.Vulnerability{
{
VulnerabilityId: "CVE-2019-0001",
PkgName: "musl",
Severity: common.Severity_HIGH,
Cvss: make(map[string]*common.CVSS),
Layer: &common.Layer{
Digest: "sha256:154ad0735c360b212b167f424d33a62305770a1fcfb6363882f5c436cfbd9812",
DiffId: "sha256:b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079",
},
LastModifiedDate: &timestamp.Timestamp{
Seconds: 1577840460,
},
PublishedDate: &timestamp.Timestamp{
Seconds: 978310860,
},
},
},
},
},
{
name: "Detect returns an error",
args: args{
req: &proto.OSDetectRequest{
OsFamily: "alpine",
OsName: "3.10.2",
Packages: []*common.Package{
{Name: "musl", Version: "1.1.22-r3"},
},
},
},
detectExpectation: ospkg.DetectExpectation{
Args: ospkg.DetectInput{
OSFamily: "alpine",
OSName: "3.10.2",
Pkgs: []ftypes.Package{
{Name: "musl", Version: "1.1.22-r3"},
},
},
ReturnArgs: ospkg.DetectOutput{
Err: xerrors.New("error"),
},
},
wantErr: "failed to detect vulnerabilities of OS packages: error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockDetector := ospkg.NewMockDetector([]ospkg.DetectExpectation{tt.detectExpectation})
mockVulnClient := new(vulnerability.MockOperation)
mockVulnClient.ApplyFillInfoExpectation(tt.fillInfoExpectation)
s := NewServer(mockDetector, mockVulnClient)
gotRes, err := s.Detect(context.TODO(), tt.args.req)
if tt.wantErr != "" {
require.NotNil(t, err, tt.name)
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
return
} else {
assert.NoError(t, err, tt.name)
}
assert.Equal(t, tt.wantRes, gotRes, tt.name)
mockDetector.AssertExpectations(t)
mockVulnClient.AssertExpectations(t)
})
}
}

View File

@@ -10,12 +10,9 @@ import (
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/trivy-db/pkg/db"
db2 "github.com/aquasecurity/trivy/pkg/db"
"github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/aquasecurity/trivy/pkg/detector/ospkg"
"github.com/aquasecurity/trivy/pkg/github"
"github.com/aquasecurity/trivy/pkg/indicator"
library2 "github.com/aquasecurity/trivy/pkg/rpc/server/library"
ospkg2 "github.com/aquasecurity/trivy/pkg/rpc/server/ospkg"
"github.com/aquasecurity/trivy/pkg/scanner/local"
"github.com/aquasecurity/trivy/pkg/vulnerability"
"github.com/spf13/afero"
@@ -27,32 +24,13 @@ import (
func initializeScanServer(localArtifactCache cache.LocalArtifactCache) *ScanServer {
applierApplier := applier.NewApplier(localArtifactCache)
detector := ospkg.Detector{}
driverFactory := library.DriverFactory{}
libraryDetector := library.NewDetector(driverFactory)
scanner := local.NewScanner(applierApplier, detector, libraryDetector)
scanner := local.NewScanner(applierApplier, detector)
config := db.Config{}
client := vulnerability.NewClient(config)
scanServer := NewScanServer(scanner, client)
return scanServer
}
func initializeOspkgServer() *ospkg2.Server {
detector := ospkg.Detector{}
config := db.Config{}
client := vulnerability.NewClient(config)
server := ospkg2.NewServer(detector, client)
return server
}
func initializeLibServer() *library2.Server {
driverFactory := library.DriverFactory{}
detector := library.NewDetector(driverFactory)
config := db.Config{}
client := vulnerability.NewClient(config)
server := library2.NewServer(detector, client)
return server
}
func initializeDBWorker(cacheDir string, quiet bool) dbWorker {
config := db.Config{}
client := github.NewClient()

View File

@@ -1,88 +0,0 @@
// Code generated by mockery v1.0.0. DO NOT EDIT.
package local
import mock "github.com/stretchr/testify/mock"
import pkgtypes "github.com/aquasecurity/trivy/pkg/types"
import time "time"
import types "github.com/aquasecurity/fanal/types"
// MockLibraryDetector is an autogenerated mock type for the LibraryDetector type
type MockLibraryDetector struct {
mock.Mock
}
type LibraryDetectorDetectArgs struct {
ImageName string
ImageNameAnything bool
FilePath string
FilePathAnything bool
Created time.Time
CreatedAnything bool
Pkgs []types.LibraryInfo
PkgsAnything bool
}
type LibraryDetectorDetectReturns struct {
DetectedVulns []pkgtypes.DetectedVulnerability
Err error
}
type LibraryDetectorDetectExpectation struct {
Args LibraryDetectorDetectArgs
Returns LibraryDetectorDetectReturns
}
func (_m *MockLibraryDetector) ApplyDetectExpectation(e LibraryDetectorDetectExpectation) {
var args []interface{}
if e.Args.ImageNameAnything {
args = append(args, mock.Anything)
} else {
args = append(args, e.Args.ImageName)
}
if e.Args.FilePathAnything {
args = append(args, mock.Anything)
} else {
args = append(args, e.Args.FilePath)
}
if e.Args.CreatedAnything {
args = append(args, mock.Anything)
} else {
args = append(args, e.Args.Created)
}
if e.Args.PkgsAnything {
args = append(args, mock.Anything)
} else {
args = append(args, e.Args.Pkgs)
}
_m.On("Detect", args...).Return(e.Returns.DetectedVulns, e.Returns.Err)
}
func (_m *MockLibraryDetector) ApplyDetectExpectations(expectations []LibraryDetectorDetectExpectation) {
for _, e := range expectations {
_m.ApplyDetectExpectation(e)
}
}
// Detect provides a mock function with given fields: imageName, filePath, created, pkgs
func (_m *MockLibraryDetector) Detect(imageName string, filePath string, created time.Time, pkgs []types.LibraryInfo) ([]pkgtypes.DetectedVulnerability, error) {
ret := _m.Called(imageName, filePath, created, pkgs)
var r0 []pkgtypes.DetectedVulnerability
if rf, ok := ret.Get(0).(func(string, string, time.Time, []types.LibraryInfo) []pkgtypes.DetectedVulnerability); ok {
r0 = rf(imageName, filePath, created, pkgs)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]pkgtypes.DetectedVulnerability)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(string, string, time.Time, []types.LibraryInfo) error); ok {
r1 = rf(imageName, filePath, created, pkgs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}

View File

@@ -8,6 +8,8 @@ import (
"strings"
"time"
"github.com/aquasecurity/trivy/pkg/detector/library"
"github.com/google/wire"
"golang.org/x/xerrors"
@@ -16,6 +18,7 @@ import (
_ "github.com/aquasecurity/fanal/analyzer/library/bundler"
_ "github.com/aquasecurity/fanal/analyzer/library/cargo"
_ "github.com/aquasecurity/fanal/analyzer/library/composer"
_ "github.com/aquasecurity/fanal/analyzer/library/jar"
_ "github.com/aquasecurity/fanal/analyzer/library/npm"
_ "github.com/aquasecurity/fanal/analyzer/library/nuget"
_ "github.com/aquasecurity/fanal/analyzer/library/pipenv"
@@ -33,7 +36,6 @@ import (
_ "github.com/aquasecurity/fanal/analyzer/pkg/rpm"
"github.com/aquasecurity/fanal/applier"
ftypes "github.com/aquasecurity/fanal/types"
libDetector "github.com/aquasecurity/trivy/pkg/detector/library"
ospkgDetector "github.com/aquasecurity/trivy/pkg/detector/ospkg"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/report"
@@ -47,8 +49,6 @@ var SuperSet = wire.NewSet(
wire.Bind(new(Applier), new(applier.Applier)),
ospkgDetector.SuperSet,
wire.Bind(new(OspkgDetector), new(ospkgDetector.Detector)),
libDetector.SuperSet,
wire.Bind(new(LibraryDetector), new(libDetector.Detector)),
NewScanner,
)
@@ -62,21 +62,15 @@ type OspkgDetector interface {
Detect(imageName, osFamily, osName string, created time.Time, pkgs []ftypes.Package) (detectedVulns []types.DetectedVulnerability, eosl bool, err error)
}
// LibraryDetector defines operation to detect library vulnerabilities
type LibraryDetector interface {
Detect(imageName, filePath string, created time.Time, pkgs []ftypes.LibraryInfo) (detectedVulns []types.DetectedVulnerability, err error)
}
// Scanner implements the OspkgDetector and LibraryDetector
type Scanner struct {
applier Applier
ospkgDetector OspkgDetector
libDetector LibraryDetector
}
// NewScanner is the factory method for Scanner
func NewScanner(applier Applier, ospkgDetector OspkgDetector, libDetector LibraryDetector) Scanner {
return Scanner{applier: applier, ospkgDetector: ospkgDetector, libDetector: libDetector}
func NewScanner(applier Applier, ospkgDetector OspkgDetector) Scanner {
return Scanner{applier: applier, ospkgDetector: ospkgDetector}
}
// Scan scans the local image and return results. TODO: fix cyclometic complexity
@@ -156,17 +150,29 @@ func (s Scanner) scanLibrary(apps []ftypes.Application, options types.ScanOption
log.Logger.Info("Trivy skips scanning programming language libraries because no supported file was detected")
return nil, nil
}
var results report.Results
for _, app := range apps {
vulns, err := s.libDetector.Detect("", app.FilePath, time.Time{}, app.Libraries)
if err != nil {
return nil, xerrors.Errorf("failed vulnerability detection of libraries: %w", err)
}
var results report.Results
printedTypes := map[string]struct{}{}
for _, app := range apps {
if len(app.Libraries) == 0 {
continue
}
if skipped(app.FilePath, options.SkipFiles, options.SkipDirectories) {
continue
}
// Prevent the same log messages from being displayed many times for the same type.
if _, ok := printedTypes[app.Type]; !ok {
log.Logger.Infof("Detecting %s vulnerabilities...", app.Type)
printedTypes[app.Type] = struct{}{}
}
log.Logger.Debugf("Detecting library vulnerabilities, type: %s, path: %s", app.Type, app.FilePath)
vulns, err := library.Detect(app.Type, app.Libraries)
if err != nil {
return nil, xerrors.Errorf("failed vulnerability detection of libraries: %w", err)
}
libReport := report.Result{
Target: app.FilePath,
Vulnerabilities: vulns,

View File

@@ -4,6 +4,12 @@ import (
"errors"
"testing"
"github.com/aquasecurity/fanal/analyzer/library"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/dbtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -26,9 +32,9 @@ func TestScanner_Scan(t *testing.T) {
tests := []struct {
name string
args args
fixtures []string
applyLayersExpectation ApplierApplyLayersExpectation
ospkgDetectExpectations []OspkgDetectorDetectExpectation
libDetectExpectations []LibraryDetectorDetectExpectation
wantResults report.Results
wantOS *ftypes.OS
wantEosl bool
@@ -41,6 +47,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"os", "library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -62,11 +69,11 @@ func TestScanner_Scan(t *testing.T) {
},
Applications: []ftypes.Application{
{
Type: "bundler",
Type: library.Bundler,
FilePath: "/app/Gemfile.lock",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Library: dtypes.Library{Name: "rails", Version: "4.0.2"},
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
@@ -108,34 +115,6 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
},
},
},
},
},
wantResults: report.Results{
{
Target: "alpine:latest (alpine 3.11)",
@@ -156,10 +135,10 @@ func TestScanner_Scan(t *testing.T) {
Target: "/app/Gemfile.lock",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
VulnerabilityID: "CVE-2014-0081",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
InstalledVersion: "4.0.2",
FixedVersion: "4.0.3, 3.2.17",
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
@@ -180,6 +159,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"os", "library"}, ListAllPackages: true},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -212,7 +192,7 @@ func TestScanner_Scan(t *testing.T) {
FilePath: "/app/Gemfile.lock",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Library: dtypes.Library{Name: "rails", Version: "4.0.2"},
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
@@ -261,34 +241,6 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
},
},
},
},
},
wantResults: report.Results{
{
Target: "alpine:latest (alpine 3.11)",
@@ -326,7 +278,7 @@ func TestScanner_Scan(t *testing.T) {
Packages: []ftypes.Package{
{
Name: "rails",
Version: "6.0",
Version: "4.0.2",
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
@@ -334,10 +286,10 @@ func TestScanner_Scan(t *testing.T) {
},
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
VulnerabilityID: "CVE-2014-0081",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
InstalledVersion: "4.0.2",
FixedVersion: "4.0.3, 3.2.17",
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
@@ -358,6 +310,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"os", "library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -371,7 +324,7 @@ func TestScanner_Scan(t *testing.T) {
FilePath: "/app/Gemfile.lock",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Library: dtypes.Library{Name: "rails", Version: "4.0.2"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -382,43 +335,15 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
},
},
wantResults: report.Results{
{
Target: "/app/Gemfile.lock",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
VulnerabilityID: "CVE-2014-0081",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
InstalledVersion: "4.0.2",
FixedVersion: "4.0.3, 3.2.17",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -436,6 +361,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"os", "library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -452,7 +378,7 @@ func TestScanner_Scan(t *testing.T) {
FilePath: "/app/Gemfile.lock",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Library: dtypes.Library{Name: "rails", Version: "4.0.2"},
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
@@ -475,34 +401,6 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
},
},
},
},
},
wantResults: report.Results{
{
Target: "alpine:latest (alpine 3.11)",
@@ -512,10 +410,10 @@ func TestScanner_Scan(t *testing.T) {
Target: "/app/Gemfile.lock",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
VulnerabilityID: "CVE-2014-0081",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
InstalledVersion: "4.0.2",
FixedVersion: "4.0.3, 3.2.17",
Layer: ftypes.Layer{
DiffID: "sha256:0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33",
},
@@ -536,6 +434,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"os", "library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -552,7 +451,7 @@ func TestScanner_Scan(t *testing.T) {
FilePath: "/app/Gemfile.lock",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Library: dtypes.Library{Name: "rails", Version: "4.0.2"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -574,43 +473,15 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
},
},
wantResults: report.Results{
{
Target: "/app/Gemfile.lock",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-10000",
VulnerabilityID: "CVE-2014-0081",
PkgName: "rails",
InstalledVersion: "6.0",
FixedVersion: "6.1",
InstalledVersion: "4.0.2",
FixedVersion: "4.0.3, 3.2.17",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -631,6 +502,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:a6d503001157aedc826853f9b67f26d35966221b158bff03849868ae4a821116"},
options: types.ScanOptions{VulnType: []string{"os", "library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:a6d503001157aedc826853f9b67f26d35966221b158bff03849868ae4a821116"},
@@ -652,6 +524,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -671,7 +544,7 @@ func TestScanner_Scan(t *testing.T) {
FilePath: "/app/Gemfile.lock",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "5.1"},
Library: dtypes.Library{Name: "rails", Version: "4.0.2"},
Layer: ftypes.Layer{
DiffID: "sha256:5cb2a5009179b1e78ecfef81a19756328bb266456cf9a9dbbcf9af8b83b735f0",
},
@@ -683,7 +556,7 @@ func TestScanner_Scan(t *testing.T) {
FilePath: "/app/composer-lock.json",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "laravel", Version: "6.0.0"},
Library: dtypes.Library{Name: "laravel/framework", Version: "6.0.0"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -694,69 +567,15 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "5.1"},
Layer: ftypes.Layer{
DiffID: "sha256:5cb2a5009179b1e78ecfef81a19756328bb266456cf9a9dbbcf9af8b83b735f0",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-11111",
PkgName: "rails",
InstalledVersion: "5.1",
FixedVersion: "5.2",
Layer: ftypes.Layer{
DiffID: "sha256:5cb2a5009179b1e78ecfef81a19756328bb266456cf9a9dbbcf9af8b83b735f0",
},
},
},
},
},
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/composer-lock.json",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "laravel", Version: "6.0.0"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-22222",
PkgName: "laravel",
InstalledVersion: "6.0.0",
FixedVersion: "6.1.0",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
},
},
wantResults: report.Results{
{
Target: "/app/Gemfile.lock",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-11111",
VulnerabilityID: "CVE-2014-0081",
PkgName: "rails",
InstalledVersion: "5.1",
FixedVersion: "5.2",
InstalledVersion: "4.0.2",
FixedVersion: "4.0.3, 3.2.17",
Layer: ftypes.Layer{
DiffID: "sha256:5cb2a5009179b1e78ecfef81a19756328bb266456cf9a9dbbcf9af8b83b735f0",
},
@@ -768,10 +587,10 @@ func TestScanner_Scan(t *testing.T) {
Target: "/app/composer-lock.json",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-22222",
PkgName: "laravel",
VulnerabilityID: "CVE-2021-21263",
PkgName: "laravel/framework",
InstalledVersion: "6.0.0",
FixedVersion: "6.1.0",
FixedVersion: "8.22.1, 7.30.3, 6.20.12",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -795,6 +614,7 @@ func TestScanner_Scan(t *testing.T) {
SkipDirectories: []string{"/usr/lib/ruby/gems"},
},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -826,7 +646,7 @@ func TestScanner_Scan(t *testing.T) {
FilePath: "app/composer-lock.json",
Libraries: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "laravel", Version: "6.0.0"},
Library: dtypes.Library{Name: "laravel/framework", Version: "6.0.0"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -837,69 +657,15 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "5.1"},
Layer: ftypes.Layer{
DiffID: "sha256:5cb2a5009179b1e78ecfef81a19756328bb266456cf9a9dbbcf9af8b83b735f0",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-11111",
PkgName: "rails",
InstalledVersion: "5.1",
FixedVersion: "5.2",
Layer: ftypes.Layer{
DiffID: "sha256:5cb2a5009179b1e78ecfef81a19756328bb266456cf9a9dbbcf9af8b83b735f0",
},
},
},
},
},
{
Args: LibraryDetectorDetectArgs{
FilePath: "app/composer-lock.json",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "laravel", Version: "6.0.0"},
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
DetectedVulns: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-22222",
PkgName: "laravel",
InstalledVersion: "6.0.0",
FixedVersion: "6.1.0",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
},
},
},
},
},
wantResults: report.Results{
{
Target: "app/composer-lock.json",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-22222",
PkgName: "laravel",
VulnerabilityID: "CVE-2021-21263",
PkgName: "laravel/framework",
InstalledVersion: "6.0.0",
FixedVersion: "6.1.0",
FixedVersion: "8.22.1, 7.30.3, 6.20.12",
Layer: ftypes.Layer{
DiffID: "sha256:9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303",
},
@@ -920,6 +686,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"os", "library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -937,6 +704,7 @@ func TestScanner_Scan(t *testing.T) {
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"os", "library"}},
},
fixtures: []string{"testdata/fixtures/happy.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -982,12 +750,13 @@ func TestScanner_Scan(t *testing.T) {
wantErr: "failed to scan OS packages",
},
{
name: "sad path: libDetector.Detect returns an error",
name: "sad path: library.Detect returns an error",
args: args{
target: "alpine:latest",
layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
options: types.ScanOptions{VulnType: []string{"library"}},
},
fixtures: []string{"testdata/fixtures/sad.yaml"},
applyLayersExpectation: ApplierApplyLayersExpectation{
Args: ApplierApplyLayersArgs{
BlobIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"},
@@ -1024,24 +793,6 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
libDetectExpectations: []LibraryDetectorDetectExpectation{
{
Args: LibraryDetectorDetectArgs{
FilePath: "/app/Gemfile.lock",
Pkgs: []ftypes.LibraryInfo{
{
Library: dtypes.Library{Name: "rails", Version: "6.0"},
Layer: ftypes.Layer{
DiffID: "sha256:9bdb2c849099a99c8ab35f6fd7469c623635e8f4479a0a5a3df61e22bae509f6",
},
},
},
},
Returns: LibraryDetectorDetectReturns{
Err: errors.New("error"),
},
},
},
wantErr: "failed to scan application libraries",
},
}
@@ -1049,16 +800,16 @@ func TestScanner_Scan(t *testing.T) {
log.InitLogger(false, true)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_ = dbtest.InitDB(t, tt.fixtures)
defer db.Close()
applier := new(MockApplier)
applier.ApplyApplyLayersExpectation(tt.applyLayersExpectation)
ospkgDetector := new(MockOspkgDetector)
ospkgDetector.ApplyDetectExpectations(tt.ospkgDetectExpectations)
libDetector := new(MockLibraryDetector)
libDetector.ApplyDetectExpectations(tt.libDetectExpectations)
s := NewScanner(applier, ospkgDetector, libDetector)
s := NewScanner(applier, ospkgDetector)
gotResults, gotOS, gotEosl, err := s.Scan(tt.args.target, "", tt.args.layerIDs, tt.args.options)
if tt.wantErr != "" {
require.NotNil(t, err, tt.name)
@@ -1074,7 +825,6 @@ func TestScanner_Scan(t *testing.T) {
applier.AssertExpectations(t)
ospkgDetector.AssertExpectations(t)
libDetector.AssertExpectations(t)
})
}
}

View File

@@ -0,0 +1,28 @@
- bucket: "GitHub Security Advisory Rubygems"
pairs:
- bucket: rails
pairs:
- key: CVE-2014-0081
value:
PatchedVersions:
- "4.0.3"
- "3.2.17"
VulnerableVersions:
- ">= 4.0.0, < 4.0.3"
- ">= 3.0.0, < 3.2.17"
- bucket: "composer::GitHub Security Advisory Composer"
pairs:
- bucket: laravel/framework
pairs:
- key: CVE-2021-21263
value:
PatchedVersions:
- 8.22.1
- 7.30.3
- 6.20.12
VulnerableVersions:
- ">= 8.0.0, < 8.22.1"
- ">= 7.0.0, < 7.30.3"
- "< 6.20.12"

View File

@@ -0,0 +1,7 @@
- bucket: "ruby-advisory-db"
pairs:
- bucket: rails
pairs:
- key: CVE-2014-0081
value:
PatchedVersions: "invalid"

View File

@@ -3,17 +3,12 @@ package utils
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"
fixtures "github.com/aquasecurity/bolt-fixtures"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/log"
)
@@ -132,26 +127,3 @@ func CopyFile(src, dst string) (int64, error) {
n, err := io.Copy(destination, source)
return n, err
}
// InitTestDB is a utility function initializing BoltDB for unit testing
func InitTestDB(t *testing.T, fixtureFiles []string) string {
// Create a temp dir
dir, err := ioutil.TempDir("", "TestDB")
require.NoError(t, err)
dbPath := db.Path(dir)
dbDir := filepath.Dir(dbPath)
err = os.MkdirAll(dbDir, 0700)
require.NoError(t, err)
// Load testdata into BoltDB
loader, err := fixtures.New(dbPath, fixtureFiles)
require.NoError(t, err)
require.NoError(t, loader.Load())
require.NoError(t, loader.Close())
// Initialize DB
require.NoError(t, db.Init(dir))
return dir
}

View File

@@ -1,243 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: rpc/detector/service.proto
package detector
import (
fmt "fmt"
common "github.com/aquasecurity/trivy/rpc/common"
proto "github.com/golang/protobuf/proto"
timestamp "github.com/golang/protobuf/ptypes/timestamp"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type OSDetectRequest struct {
OsFamily string `protobuf:"bytes,1,opt,name=os_family,json=osFamily,proto3" json:"os_family,omitempty"`
OsName string `protobuf:"bytes,2,opt,name=os_name,json=osName,proto3" json:"os_name,omitempty"`
Packages []*common.Package `protobuf:"bytes,3,rep,name=packages,proto3" json:"packages,omitempty"`
ImageName string `protobuf:"bytes,4,opt,name=image_name,json=imageName,proto3" json:"image_name,omitempty"`
Created *timestamp.Timestamp `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *OSDetectRequest) Reset() { *m = OSDetectRequest{} }
func (m *OSDetectRequest) String() string { return proto.CompactTextString(m) }
func (*OSDetectRequest) ProtoMessage() {}
func (*OSDetectRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_93e16dbd737b8924, []int{0}
}
func (m *OSDetectRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_OSDetectRequest.Unmarshal(m, b)
}
func (m *OSDetectRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_OSDetectRequest.Marshal(b, m, deterministic)
}
func (m *OSDetectRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_OSDetectRequest.Merge(m, src)
}
func (m *OSDetectRequest) XXX_Size() int {
return xxx_messageInfo_OSDetectRequest.Size(m)
}
func (m *OSDetectRequest) XXX_DiscardUnknown() {
xxx_messageInfo_OSDetectRequest.DiscardUnknown(m)
}
var xxx_messageInfo_OSDetectRequest proto.InternalMessageInfo
func (m *OSDetectRequest) GetOsFamily() string {
if m != nil {
return m.OsFamily
}
return ""
}
func (m *OSDetectRequest) GetOsName() string {
if m != nil {
return m.OsName
}
return ""
}
func (m *OSDetectRequest) GetPackages() []*common.Package {
if m != nil {
return m.Packages
}
return nil
}
func (m *OSDetectRequest) GetImageName() string {
if m != nil {
return m.ImageName
}
return ""
}
func (m *OSDetectRequest) GetCreated() *timestamp.Timestamp {
if m != nil {
return m.Created
}
return nil
}
type DetectResponse struct {
Vulnerabilities []*common.Vulnerability `protobuf:"bytes,1,rep,name=vulnerabilities,proto3" json:"vulnerabilities,omitempty"`
Eosl bool `protobuf:"varint,2,opt,name=eosl,proto3" json:"eosl,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DetectResponse) Reset() { *m = DetectResponse{} }
func (m *DetectResponse) String() string { return proto.CompactTextString(m) }
func (*DetectResponse) ProtoMessage() {}
func (*DetectResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_93e16dbd737b8924, []int{1}
}
func (m *DetectResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DetectResponse.Unmarshal(m, b)
}
func (m *DetectResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DetectResponse.Marshal(b, m, deterministic)
}
func (m *DetectResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_DetectResponse.Merge(m, src)
}
func (m *DetectResponse) XXX_Size() int {
return xxx_messageInfo_DetectResponse.Size(m)
}
func (m *DetectResponse) XXX_DiscardUnknown() {
xxx_messageInfo_DetectResponse.DiscardUnknown(m)
}
var xxx_messageInfo_DetectResponse proto.InternalMessageInfo
func (m *DetectResponse) GetVulnerabilities() []*common.Vulnerability {
if m != nil {
return m.Vulnerabilities
}
return nil
}
func (m *DetectResponse) GetEosl() bool {
if m != nil {
return m.Eosl
}
return false
}
type LibDetectRequest struct {
FilePath string `protobuf:"bytes,1,opt,name=file_path,json=filePath,proto3" json:"file_path,omitempty"`
Libraries []*common.Library `protobuf:"bytes,2,rep,name=libraries,proto3" json:"libraries,omitempty"`
ImageName string `protobuf:"bytes,3,opt,name=image_name,json=imageName,proto3" json:"image_name,omitempty"`
Created *timestamp.Timestamp `protobuf:"bytes,4,opt,name=created,proto3" json:"created,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LibDetectRequest) Reset() { *m = LibDetectRequest{} }
func (m *LibDetectRequest) String() string { return proto.CompactTextString(m) }
func (*LibDetectRequest) ProtoMessage() {}
func (*LibDetectRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_93e16dbd737b8924, []int{2}
}
func (m *LibDetectRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LibDetectRequest.Unmarshal(m, b)
}
func (m *LibDetectRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LibDetectRequest.Marshal(b, m, deterministic)
}
func (m *LibDetectRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_LibDetectRequest.Merge(m, src)
}
func (m *LibDetectRequest) XXX_Size() int {
return xxx_messageInfo_LibDetectRequest.Size(m)
}
func (m *LibDetectRequest) XXX_DiscardUnknown() {
xxx_messageInfo_LibDetectRequest.DiscardUnknown(m)
}
var xxx_messageInfo_LibDetectRequest proto.InternalMessageInfo
func (m *LibDetectRequest) GetFilePath() string {
if m != nil {
return m.FilePath
}
return ""
}
func (m *LibDetectRequest) GetLibraries() []*common.Library {
if m != nil {
return m.Libraries
}
return nil
}
func (m *LibDetectRequest) GetImageName() string {
if m != nil {
return m.ImageName
}
return ""
}
func (m *LibDetectRequest) GetCreated() *timestamp.Timestamp {
if m != nil {
return m.Created
}
return nil
}
func init() {
proto.RegisterType((*OSDetectRequest)(nil), "trivy.detector.OSDetectRequest")
proto.RegisterType((*DetectResponse)(nil), "trivy.detector.DetectResponse")
proto.RegisterType((*LibDetectRequest)(nil), "trivy.detector.LibDetectRequest")
}
func init() { proto.RegisterFile("rpc/detector/service.proto", fileDescriptor_93e16dbd737b8924) }
var fileDescriptor_93e16dbd737b8924 = []byte{
// 422 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xd1, 0x8a, 0xd3, 0x40,
0x14, 0x86, 0xc9, 0xb6, 0x76, 0xdb, 0x53, 0xd8, 0x95, 0x01, 0x31, 0x64, 0xd1, 0x2d, 0xbd, 0xea,
0xd5, 0x04, 0xbb, 0xe2, 0x03, 0x88, 0x0a, 0xca, 0xa2, 0x4b, 0x14, 0x45, 0x6f, 0xca, 0x64, 0xf6,
0x34, 0x1d, 0x36, 0xd3, 0x93, 0xce, 0x4c, 0x0a, 0x79, 0x34, 0x9f, 0xc2, 0x57, 0x92, 0x4e, 0x98,
0x6a, 0xa2, 0xe8, 0xde, 0x4d, 0xe6, 0xff, 0xcf, 0x7f, 0xce, 0xf9, 0x32, 0x90, 0x98, 0x4a, 0xa6,
0xb7, 0xe8, 0x50, 0x3a, 0x32, 0xa9, 0x45, 0xb3, 0x57, 0x12, 0x79, 0x65, 0xc8, 0x11, 0x3b, 0x73,
0x46, 0xed, 0x1b, 0x1e, 0xd4, 0xe4, 0xb2, 0x20, 0x2a, 0x4a, 0x4c, 0xbd, 0x9a, 0xd7, 0xeb, 0xd4,
0x29, 0x8d, 0xd6, 0x09, 0x5d, 0xb5, 0x05, 0xc9, 0x8b, 0x42, 0xb9, 0x4d, 0x9d, 0x73, 0x49, 0x3a,
0x15, 0xbb, 0x5a, 0x58, 0x94, 0xb5, 0x51, 0xae, 0x49, 0x7d, 0x50, 0x7a, 0x68, 0x25, 0x49, 0x6b,
0xda, 0x76, 0x1b, 0xcd, 0x7f, 0x44, 0x70, 0xfe, 0xe1, 0xe3, 0x2b, 0xdf, 0x27, 0xc3, 0x5d, 0x8d,
0xd6, 0xb1, 0x0b, 0x98, 0x90, 0x5d, 0xad, 0x85, 0x56, 0x65, 0x13, 0x47, 0xb3, 0x68, 0x31, 0xc9,
0xc6, 0x64, 0xdf, 0xf8, 0x6f, 0xf6, 0x18, 0x4e, 0xc9, 0xae, 0xb6, 0x42, 0x63, 0x7c, 0xe2, 0xa5,
0x11, 0xd9, 0xf7, 0x42, 0x23, 0x7b, 0x06, 0xe3, 0x4a, 0xc8, 0x3b, 0x51, 0xa0, 0x8d, 0x07, 0xb3,
0xc1, 0x62, 0xba, 0x7c, 0xc4, 0xdb, 0x2d, 0xda, 0xc6, 0xfc, 0xa6, 0x55, 0xb3, 0xa3, 0x8d, 0x3d,
0x01, 0x50, 0x5a, 0x14, 0xd8, 0xc6, 0x0d, 0x7d, 0xdc, 0xc4, 0xdf, 0xf8, 0xc4, 0xe7, 0x70, 0x2a,
0x0d, 0x0a, 0x87, 0xb7, 0xf1, 0x83, 0x59, 0xb4, 0x98, 0x2e, 0x13, 0xde, 0x62, 0xe0, 0x01, 0x03,
0xff, 0x14, 0x30, 0x64, 0xc1, 0x3a, 0xbf, 0x83, 0xb3, 0xb0, 0x8e, 0xad, 0x68, 0x6b, 0x91, 0xbd,
0x86, 0xf3, 0x7d, 0x5d, 0x6e, 0xd1, 0x88, 0x5c, 0x95, 0xca, 0x29, 0xb4, 0x71, 0xe4, 0x07, 0xbc,
0xe8, 0x0e, 0xf8, 0xf9, 0x37, 0x53, 0x93, 0xf5, 0x6b, 0x18, 0x83, 0x21, 0x92, 0x2d, 0xfd, 0xda,
0xe3, 0xcc, 0x9f, 0xe7, 0xdf, 0x23, 0x78, 0x78, 0xad, 0xf2, 0x3f, 0xf8, 0xad, 0x55, 0x89, 0xab,
0x4a, 0xb8, 0x4d, 0xe0, 0x77, 0xb8, 0xb8, 0x11, 0x6e, 0xc3, 0xae, 0x60, 0x52, 0xaa, 0xdc, 0x08,
0x73, 0x18, 0xe3, 0xe4, 0x6f, 0x9c, 0xae, 0xbd, 0xdc, 0x64, 0xbf, 0x7c, 0x3d, 0x50, 0x83, 0x7f,
0x80, 0x1a, 0xde, 0x1b, 0xd4, 0xf2, 0x0b, 0x40, 0xf8, 0xf3, 0x64, 0xd8, 0x5b, 0x18, 0xb5, 0x67,
0x76, 0xc9, 0xbb, 0x8f, 0x8f, 0xf7, 0xde, 0x47, 0xf2, 0xb4, 0x6f, 0xe8, 0xf2, 0x5e, 0x7e, 0x85,
0xe9, 0x91, 0x09, 0x19, 0xf6, 0xee, 0x98, 0x3c, 0xeb, 0x17, 0xf6, 0xd1, 0xfd, 0x2f, 0xfa, 0x25,
0x7c, 0x1b, 0x07, 0x29, 0x1f, 0xf9, 0xe5, 0xae, 0x7e, 0x06, 0x00, 0x00, 0xff, 0xff, 0x60, 0x68,
0xcc, 0x2b, 0x48, 0x03, 0x00, 0x00,
}

View File

@@ -1,37 +0,0 @@
// for backward compatibility
syntax = "proto3";
import "google/protobuf/timestamp.proto";
package trivy.detector;
option go_package = "detector";
import "github.com/aquasecurity/trivy/rpc/common/service.proto";
service OSDetector {
rpc Detect(OSDetectRequest) returns (DetectResponse);
}
message OSDetectRequest {
string os_family = 1;
string os_name = 2;
repeated common.Package packages = 3;
string image_name = 4;
google.protobuf.Timestamp created = 5;
}
message DetectResponse {
repeated common.Vulnerability vulnerabilities = 1;
bool eosl = 2;
}
service LibDetector {
rpc Detect(LibDetectRequest) returns (DetectResponse);
}
message LibDetectRequest {
string file_path = 1;
repeated common.Library libraries = 2;
string image_name = 3;
google.protobuf.Timestamp created = 4;
}

File diff suppressed because it is too large Load Diff