mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 07:40:48 -08:00
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:
@@ -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
15
go.mod
@@ -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
34
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
|
||||
5
pkg/cache/remote_test.go
vendored
5
pkg/cache/remote_test.go
vendored
@@ -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
34
pkg/dbtest/db.go
Normal 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
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
33
pkg/detector/library/maven/compare.go
Normal file
33
pkg/detector/library/maven/compare.go
Normal 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
|
||||
}
|
||||
87
pkg/detector/library/maven/compare_test.go
Normal file
87
pkg/detector/library/maven/compare_test.go
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
})
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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: ×tamp.Timestamp{
|
||||
Seconds: 1577840460,
|
||||
},
|
||||
PublishedDate: ×tamp.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)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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: ×tamp.Timestamp{
|
||||
Seconds: 1577840460,
|
||||
},
|
||||
PublishedDate: ×tamp.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)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
28
pkg/scanner/local/testdata/fixtures/happy.yaml
vendored
Normal file
28
pkg/scanner/local/testdata/fixtures/happy.yaml
vendored
Normal 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"
|
||||
|
||||
7
pkg/scanner/local/testdata/fixtures/sad.yaml
vendored
Normal file
7
pkg/scanner/local/testdata/fixtures/sad.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
- bucket: "ruby-advisory-db"
|
||||
pairs:
|
||||
- bucket: rails
|
||||
pairs:
|
||||
- key: CVE-2014-0081
|
||||
value:
|
||||
PatchedVersions: "invalid"
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user