Compare commits

..

6 Commits

Author SHA1 Message Date
Simarpreet Singh
78b7529172 Add image subcommand (#493)
* config_test: Add missing assertions for TestNew

Signed-off-by: Simarpreet Singh <simar@linux.com>

* integration: Add integration tests for image subcommand.

Signed-off-by: Simarpreet Singh <simar@linux.com>

* refactor: bump up urfave/cli to v2.0

* refactor: apply DIY to image flags

* refactor: reorder sub commands

* feat: set hidden to global image options

* test(integration): insert --cache-dir before sub command

* README: update readme to reflect new usage

Signed-off-by: Simarpreet Singh <simar@linux.com>

* chore(README): add image subcommand

* fix(flags): define aliases according to urfave/cli v2.0 style

Co-authored-by: knqyf263 <knqyf263@gmail.com>
2020-05-25 12:06:15 +03:00
Teppei Fukuda
e2bcb44687 fix: remove help template (#500) 2020-05-25 11:28:29 +03:00
Simarpreet Singh
a57c27eeec vulnerability: Add CVSS Vectors to JSON output. (#484)
* vulnerability: Add CVSS Vectors to JSON output.

Now Trivy will display the CVSS Vectors presented by various
vendors as part of the JSON output. This can be seen as follows:

```
      {
        "VulnerabilityID": "CVE-2019-9923",
        "PkgName": "tar",
        "InstalledVersion": "1.30+dfsg-6",
        "Layer": {
          "Digest": "sha256:90fe46dd819953eb995f9cc9c326130abe9dd0b3993a998e12c01d0218a0b831",
          "DiffID": "sha256:e40d297cf5f89a9822af4c2f63caa2f2085d5aa188137506918e603774b083cb"
        },
        "SeveritySource": "debian",
        "Title": "tar: null-pointer dereference in pax_decode_header in sparse.c",
        "Description": "pax_decode_header in sparse.c in GNU Tar before 1.32 had a NULL pointer dereference when parsing certain archives that have malformed extended headers.",
        "Severity": "LOW",
        "VendorVectors": {
          "nvd": {
            "v2": "AV:N/AC:L/Au:N/C:N/I:N/A:P",
            "v3": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "redhat": {
            "v3": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L"
          }
        },
        "References": [
          "http://git.savannah.gnu.org/cgit/tar.git/commit/?id=cb07844454d8cc9fb21f53ace75975f91185a120",
          "http://lists.opensuse.org/opensuse-security-announce/2019-04/msg00077.html",
          "http://savannah.gnu.org/bugs/?55369",
          "https://bugs.launchpad.net/ubuntu/+source/tar/+bug/1810241"
        ]
      },
```

Signed-off-by: Simarpreet Singh <simar@linux.com>

* mod: Update to latest master of trivy-db

Signed-off-by: Simarpreet Singh <simar@linux.com>

* vulnerability_test: Fix tests for new struct type

Signed-off-by: Simarpreet Singh <simar@linux.com>
2020-05-21 14:22:14 -07:00
Teppei Fukuda
926f323a72 feat: support registry token (#482)
* feat: support registry token

* chore(mod): update

* test(integration): add registry tests

* chore(mod): update

* test(integration): comment in terminate

Co-authored-by: Simarpreet Singh <simar@linux.com>
2020-05-19 20:49:27 +03:00
Teppei Fukuda
aa20adb22b chore: bump up urfave/cli to v2 (#499) 2020-05-18 14:43:06 +03:00
Teppei Fukuda
3e0779a78d chore(doc): update README (#490) 2020-05-12 15:17:06 +03:00
25 changed files with 1069 additions and 317 deletions

132
README.md
View File

@@ -134,7 +134,7 @@ $ rpm -ivh https://github.com/aquasecurity/trivy/releases/download/{TRIVY_VERSIO
Add repository to `/etc/apt/sources.list.d`.
```
$ sudo apt-get install wget apt-transport-https gnupg lsb-release
$ sudo apt-get install wget apt-transport-https gnupg lsb-release
$ wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
$ echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
$ sudo apt-get update
@@ -195,13 +195,13 @@ Simply specify an image name (and a tag). **The `latest` tag should be avoided a
## Basic
```
$ trivy [YOUR_IMAGE_NAME]
$ trivy image [YOUR_IMAGE_NAME]
```
For example:
```
$ trivy python:3.4-alpine
$ trivy image python:3.4-alpine
```
<details>
@@ -278,7 +278,7 @@ Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
Simply specify an image name (and a tag).
```
$ trivy knqyf263/vuln-image:1.2.3
$ trivy image knqyf263/vuln-image:1.2.3
```
<details>
@@ -492,7 +492,7 @@ Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
```
$ docker save ruby:2.3.0-alpine3.9 -o ruby-2.3.0.tar
$ trivy --input ruby-2.3.0.tar
$ trivy image --input ruby-2.3.0.tar
```
<details>
@@ -536,6 +536,8 @@ Total: 7447 (UNKNOWN: 5, LOW: 326, MEDIUM: 5695, HIGH: 1316, CRITICAL: 105)
...
```
</details>
### Scan an OCI image
An image directory compliant with "Open Container Image Layout Specification".
@@ -543,22 +545,21 @@ Buildah:
```
$ buildah push docker.io/library/alpine:3.11 oci:/path/to/alpine
$ trivy --input /path/to/alpine
$ trivy image --input /path/to/alpine
```
Skopeo:
```
$ skopeo copy docker-daemon:alpine:3.11 oci:/path/to/alpine
$ trivy --input /path/to/alpine
$ trivy image --input /path/to/alpine
```
</details>
### Save the results as JSON
```
$ trivy -f json -o results.json golang:1.12-alpine
$ trivy image -f json -o results.json golang:1.12-alpine
```
<details>
@@ -683,7 +684,7 @@ $ trivy -f json -o results.json golang:1.12-alpine
### Save the results using a template
```
$ trivy --format template --template "{{ range . }} {{ .Target }} {{ end }}" golang:1.12-alpine
$ trivy image --format template --template "{{ range . }} {{ .Target }} {{ end }}" golang:1.12-alpine
```
<details>
<summary>Result</summary>
@@ -696,13 +697,13 @@ $ trivy --format template --template "{{ range . }} {{ .Target }} {{ end }}" gol
You can load templates from a file prefixing the template path with an @.
```
$ trivy --format template --template "@/path/to/template" golang:1.12-alpine
$ trivy image --format template --template "@/path/to/template" golang:1.12-alpine
```
### Filter the vulnerabilities by severities
```
$ trivy --severity HIGH,CRITICAL ruby:2.3.0
$ trivy image --severity HIGH,CRITICAL ruby:2.4.0
```
<details>
@@ -712,7 +713,7 @@ $ trivy --severity HIGH,CRITICAL ruby:2.3.0
2019-05-16T01:51:46.255+0900 INFO Updating vulnerability database...
2019-05-16T01:51:49.213+0900 INFO Detecting Debian vulnerabilities...
ruby:2.3.0 (debian 8.4)
ruby:2.4.0 (debian 8.7)
=======================
Total: 1785 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1680, CRITICAL: 105)
@@ -766,7 +767,7 @@ Total: 1785 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1680, CRITICAL: 105)
### Filter the vulnerabilities by type
```
$ trivy --vuln-type os ruby:2.3.0
$ trivy image --vuln-type os ruby:2.4.0
```
Available values:
@@ -784,7 +785,7 @@ Available values:
2019-05-22T19:36:52.390+0200 INFO Updating pipenv Security DB...
2019-05-22T19:36:53.406+0200 INFO Detecting pipenv vulnerabilities...
ruby:2.3.0 (debian 8.4)
ruby:2.4.0 (debian 8.7)
Total: 4751 (UNKNOWN: 1, LOW: 150, MEDIUM: 3504, HIGH: 1013, CRITICAL: 83)
+---------+------------------+----------+-------------------+---------------+----------------------------------+
@@ -904,7 +905,7 @@ Total: 4751 (UNKNOWN: 1, LOW: 150, MEDIUM: 3504, HIGH: 1013, CRITICAL: 83)
`Trivy` always updates its vulnerability database when it starts operating. This is usually fast, as it is a difference update. But if you want to skip even that, use the `--skip-update` option.
```
$ trivy --skip-update python:3.4-alpine3.9
$ trivy image --skip-update python:3.4-alpine3.9
```
<details>
@@ -930,11 +931,10 @@ Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
### Only download vulnerability database
You can also ask `Trivy` to simply retrieve the vulnerability database. This is useful to initialize workers in Continuous Integration systems. In the first run, the `--only-update` option is silently ignored.
You can also ask `Trivy` to simply retrieve the vulnerability database. This is useful to initialize workers in Continuous Integration systems.
```
$ trivy --download-db-only
$ trivy --download-db-only --only-update alpine
$ trivy image --download-db-only
```
### Ignore unfixed vulnerabilities
@@ -943,7 +943,7 @@ By default, `Trivy` also detects unpatched/unfixed vulnerabilities. This means y
If you would like to ignore them, use the `--ignore-unfixed` option.
```
$ trivy --ignore-unfixed ruby:2.3.0
$ trivy image --ignore-unfixed ruby:2.4.0
```
<details>
@@ -953,7 +953,7 @@ $ trivy --ignore-unfixed ruby:2.3.0
2019-05-16T12:49:52.656+0900 INFO Updating vulnerability database...
2019-05-16T12:50:14.786+0900 INFO Detecting Debian vulnerabilities...
ruby:2.3.0 (debian 8.4)
ruby:2.4.0 (debian 8.7)
=======================
Total: 4730 (UNKNOWN: 1, LOW: 145, MEDIUM: 3487, HIGH: 1014, CRITICAL: 83)
@@ -991,7 +991,7 @@ By default, `Trivy` exits with code 0 even when vulnerabilities are detected.
Use the `--exit-code` option if you want to exit with a non-zero exit code.
```
$ trivy --exit-code 1 python:3.4-alpine3.9
$ trivy image --exit-code 1 python:3.4-alpine3.9
```
<details>
@@ -1018,8 +1018,8 @@ Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
This option is useful for CI/CD. In the following example, the test will fail only when a critical vulnerability is found.
```
$ trivy --exit-code 0 --severity MEDIUM,HIGH ruby:2.3.0
$ trivy --exit-code 1 --severity CRITICAL ruby:2.3.0
$ trivy image --exit-code 0 --severity MEDIUM,HIGH ruby:2.4.0
$ trivy image --exit-code 1 --severity CRITICAL ruby:2.4.0
```
### Ignore the specified vulnerabilities
@@ -1034,7 +1034,7 @@ CVE-2018-14618
# No impact in our settings
CVE-2019-1543
$ trivy python:3.4-alpine3.9
$ trivy image python:3.4-alpine3.9
```
<details>
@@ -1055,7 +1055,7 @@ Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
### Specify cache directory
```
$ trivy --cache-dir /tmp/trivy/ python:3.4-alpine3.9
$ trivy --cache-dir /tmp/trivy/ image python:3.4-alpine3.9
```
### Clear image caches
@@ -1065,7 +1065,7 @@ The `--clear-cache` option removes image caches. This option is useful if the im
**The scan is not performed.**
```
$ trivy --clear-cache
$ trivy image --clear-cache
```
<details>
@@ -1083,7 +1083,7 @@ $ trivy --clear-cache
The `--reset` option removes all caches and database. After this, it takes a long time as the vulnerability database needs to be rebuilt locally.
```
$ trivy --reset
$ trivy image --reset
```
<details>
@@ -1105,7 +1105,7 @@ To find the additional information, you can search vulnerability details on the
https://nvd.nist.gov/vuln/search
```
$ trivy --light alpine:3.10
$ trivy image --light alpine:3.10
```
`--light` option doesn't display titles like the following example.
@@ -1425,41 +1425,49 @@ Trivy scans a tar image with the following format.
```
NAME:
trivy - A simple and comprehensive vulnerability scanner for containers
USAGE:
main [options] image_name
VERSION:
0.2.0
OPTIONS:
--template value, -t value output template [$TRIVY_TEMPLATE]
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
--output value, -o value output file name [$TRIVY_OUTPUT]
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
--skip-update skip db update [$TRIVY_SKIP_UPDATE]
--download-db-only download/update vulnerability database but don't run a scan [$TRIVY_DOWNLOAD_DB_ONLY]
--reset remove all caches and database [$TRIVY_RESET]
--clear-cache, -c clear image caches [$TRIVY_CLEAR_CACHE]
--quiet, -q suppress progress bar and log output [$TRIVY_QUIET]
--no-progress suppress progress bar [$TRIVY_NO_PROGRESS]
--ignore-unfixed display only fixed vulnerabilities [$TRIVY_IGNORE_UNFIXED]
--debug, -d debug mode [$TRIVY_DEBUG]
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
--cache-dir value use as cache directory, but image cache is stored in /path/to/cache/fanal (default: "/Users/teppei/Library/Caches/trivy") [$TRIVY_CACHE_DIR]
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
--timeout value docker timeout (default: 1m0s) [$TRIVY_TIMEOUT]
--light light mode: it's faster, but vulnerability descriptions and references are not displayed
--only-update value deprecated [$TRIVY_ONLY_UPDATE]
--refresh deprecated [$TRIVY_REFRESH]
--auto-refresh deprecated [$TRIVY_AUTO_REFRESH]
--help, -h show help
--version, -v print the version
trivy - A simple and comprehensive vulnerability scanner for containers
USAGE:
trivy image [options] image_name
VERSION:
v0.7.0
OPTIONS:
--quiet suppress progress bar and log output (default: false) [$TRIVY_QUIET]
--debug debug mode (default: false) [$TRIVY_DEBUG]
--cache-dir value cache directory (default: "/Users/simar/Library/Caches/trivy") [$TRIVY_CACHE_DIR]
--help, -h show help (default: false)
--version, -v print the version (default: false)
```
## Sub commands
Trivy has two sub commands, client and server.
Trivy has three sub commands, image, client and server.
```
NAME:
trivy image - scan an image
USAGE:
trivy image [command options] [arguments...]
OPTIONS:
--template value output template [$TRIVY_TEMPLATE]
--format value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
--input value input file path instead of image name [$TRIVY_INPUT]
--severity value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
--output value output file name [$TRIVY_OUTPUT]
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
--skip-update skip db update (default: false) [$TRIVY_SKIP_UPDATE]
--download-db-only download/update vulnerability database but don't run a scan (default: false) [$TRIVY_DOWNLOAD_DB_ONLY]
--reset remove all caches and database (default: false) [$TRIVY_RESET]
--clear-cache clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
--removed-pkgs detect vulnerabilities of removed packages (only for Alpine) (default: false) [$TRIVY_REMOVED_PKGS]
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
--timeout value docker timeout (default: 2m0s) [$TRIVY_TIMEOUT]
--light light mode: it's faster, but vulnerability descriptions and references are not displayed (default: false) [$TRIVY_LIGHT]
--help, -h show help (default: false)
```
```
NAME:
@@ -1667,7 +1675,7 @@ $ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10
Try again with `--reset` option:
```
$ trivy --reset
$ trivy image --reset
```
# Related Projects

9
go.mod
View File

@@ -3,15 +3,17 @@ module github.com/aquasecurity/trivy
go 1.13
require (
github.com/aquasecurity/fanal v0.0.0-20200504143803-30a561989059
github.com/aquasecurity/fanal v0.0.0-20200505074551-9239a362deca
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b
github.com/aquasecurity/trivy-db v0.0.0-20200430091154-7c0a6e1ad398
github.com/aquasecurity/trivy-db v0.0.0-20200514134639-7e57e3e02470
github.com/caarlos0/env/v6 v6.0.0
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cheggaaa/pb/v3 v3.0.3
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7
github.com/docker/go-connections v0.4.0
github.com/genuinetools/reg v0.16.0
github.com/golang/protobuf v1.3.3
github.com/google/go-containerregistry v0.0.0-20200331213917-3d03ed9b1ca2
github.com/google/go-github/v28 v28.1.1
github.com/google/wire v0.3.0
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
@@ -22,8 +24,9 @@ require (
github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a
github.com/spf13/afero v1.2.2
github.com/stretchr/testify v1.4.0
github.com/testcontainers/testcontainers-go v0.3.1
github.com/twitchtv/twirp v5.10.1+incompatible
github.com/urfave/cli v1.22.1
github.com/urfave/cli/v2 v2.2.0
go.uber.org/atomic v1.5.1 // indirect
go.uber.org/multierr v1.4.0 // indirect
go.uber.org/zap v1.13.0

28
go.sum
View File

@@ -31,6 +31,7 @@ github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcy
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
@@ -42,14 +43,14 @@ github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdc
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aquasecurity/fanal v0.0.0-20200504143803-30a561989059 h1:FLQkluzBXeQvyNAMNtFpvd0qMbxLeYVdP6B/Pxx/d54=
github.com/aquasecurity/fanal v0.0.0-20200504143803-30a561989059/go.mod h1:3H3F3x2XtcdFH3o1LQJEzfu2sS/rf+XufPIngMZrKO4=
github.com/aquasecurity/fanal v0.0.0-20200505074551-9239a362deca h1:xNs3bLA5k8hySXtV6S6oOc88zDxpL2gXo4Z2qPXmx4c=
github.com/aquasecurity/fanal v0.0.0-20200505074551-9239a362deca/go.mod h1:3H3F3x2XtcdFH3o1LQJEzfu2sS/rf+XufPIngMZrKO4=
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b h1:55Ulc/gvfWm4ylhVaR7MxOwujRjA6et7KhmUbSgUFf4=
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b/go.mod h1:BpNTD9vHfrejKsED9rx04ldM1WIbeyXGYxUrqTVwxVQ=
github.com/aquasecurity/testdocker v0.0.0-20200426142840-5f05bce6f12a h1:hsw7PpiymXP64evn/K7gsj3hWzMqLrdoeE6JkqDocVg=
github.com/aquasecurity/testdocker v0.0.0-20200426142840-5f05bce6f12a/go.mod h1:psfu0MVaiTDLpNxCoNsTeILSKY2EICBwv345f3M+Ffs=
github.com/aquasecurity/trivy-db v0.0.0-20200430091154-7c0a6e1ad398 h1:+13ICJ+UlP/1aHZixBv1EdhS+4kTdY0ASJOktnCUOfI=
github.com/aquasecurity/trivy-db v0.0.0-20200430091154-7c0a6e1ad398/go.mod h1:8mrJtzlmPGWO1uVwPurDrybthyA/eZ7voMO9b54rdRw=
github.com/aquasecurity/trivy-db v0.0.0-20200514134639-7e57e3e02470 h1:6VE+g4AK2uivPqZtVk/QtcCBb2rUjAvKqDNexSgqMC0=
github.com/aquasecurity/trivy-db v0.0.0-20200514134639-7e57e3e02470/go.mod h1:F77bF2nRbcH4EIhhcNEP585MoAKdLpEP3dihF9V1Hbw=
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=
@@ -77,6 +78,7 @@ github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMX
github.com/containerd/containerd v1.3.3 h1:LoIzb5y9x5l8VKAlyrbusNPXqBY0+kviRloxFUMFwKc=
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20180921161001-7f53d412b9eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/coreos/clair v0.0.0-20180919182544-44ae4bc9590a/go.mod h1:uXhHPWAoRqw0jJc2f8RrPCwRhIo9otQ8OEWUFtpCiwA=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -145,6 +147,7 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/genuinetools/pkg v0.0.0-20180910213200-1c141f661797/go.mod h1:XTcrCYlXPxnxL2UpnwuRn7tcaTn9HAhxFoFJucootk8=
github.com/genuinetools/reg v0.16.0 h1:ZhLZPT+aUGHLfy45Ub5FLWik+3Dij1iwaj8A/GyAZBw=
@@ -169,7 +172,9 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U=
github.com/go-redis/redis v6.15.7+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -240,6 +245,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
@@ -327,10 +333,12 @@ github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a/go.mod h1
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
@@ -338,6 +346,7 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ=
github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
@@ -373,6 +382,7 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
@@ -411,6 +421,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
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=
github.com/twitchtv/twirp v5.10.1+incompatible h1:35js8ID9rYPKkZ0qWnuZw+q+OuCWM1GIibu1F1YImjA=
@@ -418,9 +429,10 @@ github.com/twitchtv/twirp v5.10.1+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3v
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c=
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@@ -448,6 +460,7 @@ golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnf
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=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -512,6 +525,7 @@ golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -601,6 +615,7 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS
gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
@@ -611,6 +626,7 @@ gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3M
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=

View File

@@ -14,7 +14,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/aquasecurity/trivy/internal"
)

View File

@@ -0,0 +1,23 @@
server:
addr: ":5001"
certificate: "/certs/cert.pem"
key: "/certs/key.pem"
token:
issuer: "Trivy auth server" # Must match issuer in the Registry config.
expiration: 900
users:
# Password is specified as a BCrypt hash. Use `htpasswd -nB USERNAME` to generate.
"admin":
password: "$2y$05$LO.vzwpWC5LZGqThvEfznu8qhb5SGqvBSWY1J3yZ4AxtMRZ3kN5jC" # badmin
"test":
password: "$2y$05$WuwBasGDAgr.QCbGIjKJaep4dhxeai9gNZdmBnQXqpKly57oNutya" # 123
acl:
- match: {account: "admin"}
actions: ["*"]
comment: "Admin has full access to everything."
- match: {account: "test"}
actions: ["pull"]
comment: "User \"test\" can pull stuff."

View File

@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC+jCCAeKgAwIBAgIRAJLJ5vw48YZwoHlC8i6VdHswDQYJKoZIhvcNAQELBQAw
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0yMDA1MDMxMTU2MzhaFw0yMTA1MDMxMTU2
MzhaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDhnepAL1Atd1xVh/TOZpTK7yHwtOrtGWNEqNkFbcyD7x9CNgUkxjO8
nc4ynEo4ARpLj+2VDLIwi93weCFj6mcz2tdHi7n0eiPR7+PSNMNpPFwablLOEtaX
XVqHhJNsHcJx6okX6ullksJoRnZGu+n1LvGRMMLWjS3UJZA6+1pujoifyrx9YXLU
qSjkRRv3Ly8HmAPJq0T19uCZiJ8qbrW1Vx3hdUILL4OlJmpjZvGKMRnolinko2Vk
0pHH5MWz0iUbqWQjHZmQWi0rDHRAFbuCqQdmFsEneXmUzExXZbyHwrTH/mrjJTCJ
YmtR7Eq80AxsWnXNI3Z0mVQ9/nZDsT31AgMBAAGjSzBJMA4GA1UdDwEB/wQEAwIF
oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuC
CWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAG7spAmpZVKOV913WhKZp8o1+
T6v/b6KUOAZ0iWXeGWO7LwnRaulkyauGav9xJUpfEw7Z/57qwTVIGZD6mZF6tt77
FsXXiQJA88LrQnt1BRTeNK8sRp4S3N1hrtY3akTit/dyQcfh3NSDttzkYsoUu0qT
DUkXD0b4eDmaD47+0Z6eIVp3aEcPMzpiy6qWc5fMjMeHjtYF4lBSF0JTWzmxNUGl
fiGhMJStQK/n73t58O7h5Adva5wRV+Km6pa+6SfOxPNUjsxXjG0LzWA9dJg/q2rs
k/ouIE05BfB3z538ncQVBTwfPMClbIiJhAs3b6ej22+j/O+vbFBmdfkpVpFRtg==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDhnepAL1Atd1xV
h/TOZpTK7yHwtOrtGWNEqNkFbcyD7x9CNgUkxjO8nc4ynEo4ARpLj+2VDLIwi93w
eCFj6mcz2tdHi7n0eiPR7+PSNMNpPFwablLOEtaXXVqHhJNsHcJx6okX6ullksJo
RnZGu+n1LvGRMMLWjS3UJZA6+1pujoifyrx9YXLUqSjkRRv3Ly8HmAPJq0T19uCZ
iJ8qbrW1Vx3hdUILL4OlJmpjZvGKMRnolinko2Vk0pHH5MWz0iUbqWQjHZmQWi0r
DHRAFbuCqQdmFsEneXmUzExXZbyHwrTH/mrjJTCJYmtR7Eq80AxsWnXNI3Z0mVQ9
/nZDsT31AgMBAAECggEBAKwwGhSMR3O7sdNxJIvVzF8orE2JtfXoN1OyTZcQGlLi
z4d3tOtA/UFJapJDp30gklHy8Y6clu3oASVCebFItyTjMwPehrgn82iI3eWS8URC
lcRySG4QAIia7bmZm+2atMi+B40icqhbnlV42VHYnpDKGAEIJtsZ+kz7shzhsj3G
yTQMFyuqk0DUmsbSVKPjryv15DXsT9Rk2pVZYFhiRw/gQpWD58GMP/HMrSz+sjuX
ZIlhSMGVWA4Yc7le4PpWI2qAZLR+X1EgkzxcMJ0kWvnvzEXFmofaYzkbEcNOlguF
Bv9kP5fh35AbQbTLykGO9h4VrfDajlHequzNBJs1z60CgYEA53cwBh42pg/fSmaO
sowpFV52ZfbfUPcuXRuaidHWougByB8P8XTMeQTse4NLt+2oat/5rdP3keGr5OR5
8q7v8/R/KY0NQOa/93BUeRDW4ntxMECWbC2p/sq2wnRKTl+yepAWrRXzk8z9vFP/
TZM5m65aj3IsZ3Bo1WG+SSf8bvsCgYEA+YgFxmiTauKRO4IVPuOqJ88yC5SQ83mF
T54ILYalG3yq/Jm1TTOzoZAoKvHrJeeZqQvjS4jSY5gc5TCrUVTdsw5nXtrRKZJs
HjtVT78qfzjCSHzImvc3Rw5+SNO2+j9yxuBSAG4tEKD3KKxSodXnKtD4CwzvRdyI
gUyjQi3Os88CgYEAgrzegkYkhe2nKKX+6bijJ+/AHl2vy1KifHKv+jJs8nzrLLbm
0XIwYBa44BbL+Oqi2yMBKv7z8hEuf03R15KZ9Ahgnv6Nwt/TBBcNj4hEZ45j42ZH
0HiGcWTcj78RjW0eKX4jYMZqW0xI8Uvcg1uqCVYUzrsle5ORkxzvVvDf82sCgYEA
4hS9tsA1IJhaoaIAgdRf7GWroBZhJlep0zMJkcX2fer8OJVDUMlRLUahPhelx9gI
vsLIkz1J8XZ2Z6kq7yuHGp4oRibXb2T8lH+JkhFP/ah9TpPQZacq7DRTcsRvelhW
M542bbFlHzXX+X/39i0Jnx9qPQjhGVjwTMYU/Pbn2r0CgYAkwwh2oq6BP3w7/4xe
giaW/5zzMA8R9ZXFfkE4OXk2vig8LzUn1IO0JeGLyHQbdg8exYxTU3zygIlSvCQP
Zbl0+RB+NHwGOqlpEDdPFXsqi1GAdWOC6FzYtBFNk9WyjFICXjB42wnfIIUQPLU1
kQKFaehfx9KR0iW1dnm3vbFlzw==
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,112 @@
package docker
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"github.com/docker/docker/client"
"github.com/docker/docker/api/types"
)
type RegistryConfig struct {
URL *url.URL
Username string
Password string
}
func (c RegistryConfig) GetAuthConfig() types.AuthConfig {
return types.AuthConfig{
Username: c.Username,
Password: c.Password,
ServerAddress: c.URL.Host,
}
}
func (c RegistryConfig) GetRegistryAuth() (string, error) {
authConfig := types.AuthConfig{
Username: c.Username,
Password: c.Password,
}
encodedJSON, err := json.Marshal(authConfig)
if err != nil {
return "", err
}
return base64.URLEncoding.EncodeToString(encodedJSON), nil
}
type Docker struct {
cli *client.Client
}
func New() (Docker, error) {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return Docker{}, err
}
return Docker{
cli: cli,
}, nil
}
// ReplicateImage tags the given imagePath and pushes it to the given dest registry.
func (d Docker) ReplicateImage(ctx context.Context, imageRef, imagePath string, dest RegistryConfig) error {
// remove existing Image if any
_, _ = d.cli.ImageRemove(ctx, imageRef, types.ImageRemoveOptions{
Force: true,
PruneChildren: true,
})
testfile, err := os.Open(imagePath)
if err != nil {
return err
}
// load image into docker engine
resp, err := d.cli.ImageLoad(ctx, testfile, true)
if err != nil {
return err
}
if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
return err
}
defer resp.Body.Close()
targetImageRef := fmt.Sprintf("%s/%s", dest.URL.Host, imageRef)
if err = d.cli.ImageTag(ctx, imageRef, targetImageRef); err != nil {
return err
}
defer func() {
_, _ = d.cli.ImageRemove(ctx, imageRef, types.ImageRemoveOptions{
Force: true,
PruneChildren: true,
})
_, _ = d.cli.ImageRemove(ctx, targetImageRef, types.ImageRemoveOptions{
Force: true,
PruneChildren: true,
})
}()
auth, err := dest.GetRegistryAuth()
if err != nil {
return err
}
pushOut, err := d.cli.ImagePush(ctx, targetImageRef, types.ImagePushOptions{RegistryAuth: auth})
if err != nil {
return err
}
defer pushOut.Close()
if _, err = io.Copy(ioutil.Discard, pushOut); err != nil {
return err
}
return nil
}

View File

@@ -20,22 +20,33 @@ import (
func TestRun_WithDockerEngine(t *testing.T) {
testCases := []struct {
name string
imageTag string
invalidImage bool
ignoreUnfixed bool
severity []string
ignoreIDs []string
testfile string
expectedOutputFile string
expectedError string
name string
withImageSubcommand bool
imageTag string
invalidImage bool
ignoreUnfixed bool
severity []string
ignoreIDs []string
testfile string
expectedOutputFile string
expectedError string
}{
// All of these cases should pass for either
// $ trivy <args>
// $ trivy image <args>
{
name: "happy path, valid image path, alpine:3.10",
imageTag: "alpine:3.10",
expectedOutputFile: "testdata/alpine-310.json.golden",
testfile: "testdata/fixtures/alpine-310.tar.gz",
},
{
name: "happy path, valid image path, with image subcommand, alpine:3.10",
withImageSubcommand: true,
imageTag: "alpine:3.10",
expectedOutputFile: "testdata/alpine-310.json.golden",
testfile: "testdata/fixtures/alpine-310.tar.gz",
},
{
name: "happy path, valid image path, alpine:3.10, ignore unfixed",
ignoreUnfixed: true,
@@ -273,7 +284,14 @@ func TestRun_WithDockerEngine(t *testing.T) {
// run trivy
app := internal.NewApp("dev")
trivyArgs := []string{"trivy", "--skip-update", "--cache-dir", cacheDir, "--format=json", "--output", of.Name()}
trivyArgs := []string{"trivy"}
trivyArgs = append(trivyArgs, "--cache-dir", cacheDir)
if tc.withImageSubcommand {
trivyArgs = append(trivyArgs, "image")
}
trivyArgs = append(trivyArgs, []string{"--skip-update", "--format=json", "--output", of.Name()}...)
if tc.ignoreUnfixed {
trivyArgs = append(trivyArgs, "--ignore-unfixed")
}

View File

@@ -1,4 +1,4 @@
// +rbuild integration
// +build integration
package integration

View File

@@ -0,0 +1,346 @@
// +build integration
package integration
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"testing"
"github.com/docker/go-connections/nat"
"github.com/google/go-containerregistry/pkg/name"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
testcontainers "github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
_ "github.com/aquasecurity/fanal/analyzer"
testdocker "github.com/aquasecurity/trivy/integration/docker"
"github.com/aquasecurity/trivy/internal"
"github.com/aquasecurity/trivy/pkg/report"
)
const (
registryImage = "registry:2"
registryPort = "5443/tcp"
authImage = "cesanta/docker_auth:1"
authPort = "5001/tcp"
authUsername = "admin"
authPassword = "badmin"
)
func setupRegistry(ctx context.Context, baseDir string, authURL *url.URL) (testcontainers.Container, error) {
req := testcontainers.ContainerRequest{
Name: "registry",
Image: registryImage,
ExposedPorts: []string{registryPort},
Env: map[string]string{
"REGISTRY_HTTP_ADDR": "0.0.0.0:5443",
"REGISTRY_HTTP_TLS_CERTIFICATE": "/certs/cert.pem",
"REGISTRY_HTTP_TLS_KEY": "/certs/key.pem",
"REGISTRY_AUTH": "token",
"REGISTRY_AUTH_TOKEN_REALM": fmt.Sprintf("%s/auth", authURL),
"REGISTRY_AUTH_TOKEN_SERVICE": "registry.docker.io",
"REGISTRY_AUTH_TOKEN_ISSUER": "Trivy auth server",
"REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE": "/certs/cert.pem",
},
BindMounts: map[string]string{
filepath.Join(baseDir, "data", "certs"): "/certs",
},
WaitingFor: wait.ForLog("listening on [::]:5443"),
}
registryC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
return registryC, err
}
func setupAuthServer(ctx context.Context, baseDir string) (testcontainers.Container, error) {
req := testcontainers.ContainerRequest{
Name: "docker_auth",
Image: authImage,
ExposedPorts: []string{authPort},
BindMounts: map[string]string{
filepath.Join(baseDir, "data", "auth_config"): "/config",
filepath.Join(baseDir, "data", "certs"): "/certs",
},
Cmd: []string{"/config/config.yml"},
}
authC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
return authC, err
}
func getURL(ctx context.Context, container testcontainers.Container, exposedPort nat.Port) (*url.URL, error) {
ip, err := container.Host(ctx)
if err != nil {
return nil, err
}
port, err := container.MappedPort(ctx, exposedPort)
if err != nil {
return nil, err
}
urlStr := fmt.Sprintf("https://%s:%s", ip, port.Port())
return url.Parse(urlStr)
}
type registryOption struct {
AuthURL *url.URL
Username string
Password string
RegistryToken bool
}
func TestRegistry(t *testing.T) {
ctx := context.Background()
baseDir, err := filepath.Abs(".")
require.NoError(t, err)
// set up auth server
authC, err := setupAuthServer(ctx, baseDir)
require.NoError(t, err)
defer authC.Terminate(ctx)
authURL, err := getURL(ctx, authC, authPort)
require.NoError(t, err)
// set up registry
registryC, err := setupRegistry(ctx, baseDir, authURL)
require.NoError(t, err)
defer registryC.Terminate(ctx)
registryURL, err := getURL(ctx, registryC, registryPort)
require.NoError(t, err)
config := testdocker.RegistryConfig{
URL: registryURL,
Username: authUsername,
Password: authPassword,
}
testCases := []struct {
name string
imageName string
imageFile string
option registryOption
golden string
wantErr string
}{
{
name: "happy path with username/password",
imageName: "alpine:3.10",
imageFile: "testdata/fixtures/alpine-310.tar.gz",
option: registryOption{
AuthURL: authURL,
Username: authUsername,
Password: authPassword,
},
golden: "testdata/alpine-310-registry.json.golden",
},
{
name: "happy path with registry token",
imageName: "alpine:3.10",
imageFile: "testdata/fixtures/alpine-310.tar.gz",
option: registryOption{
AuthURL: authURL,
Username: authUsername,
Password: authPassword,
RegistryToken: true,
},
golden: "testdata/alpine-310-registry.json.golden",
},
{
name: "sad path",
imageName: "alpine:3.10",
imageFile: "testdata/fixtures/alpine-310.tar.gz",
wantErr: "unsupported status code 401; body: Auth failed",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
d, err := testdocker.New()
require.NoError(t, err)
s := fmt.Sprintf("%s/%s", registryURL.Host, tc.imageName)
imageRef, err := name.ParseReference(s)
require.NoError(t, err)
// 1. Load a test image from the tar file, tag it and push to the test registry.
err = d.ReplicateImage(ctx, tc.imageName, tc.imageFile, config)
require.NoError(t, err)
// 2. Scan it
resultFile, err := scan(imageRef, baseDir, tc.option)
if tc.wantErr != "" {
require.NotNil(t, err)
require.Contains(t, err.Error(), tc.wantErr, err)
return
} else {
require.NoError(t, err)
}
defer os.Remove(resultFile)
// 3. Compare want and got
golden, err := os.Open(tc.golden)
assert.NoError(t, err)
var want report.Results
err = json.NewDecoder(golden).Decode(&want)
require.NoError(t, err)
result, err := os.Open(resultFile)
assert.NoError(t, err)
var got report.Results
err = json.NewDecoder(result).Decode(&got)
require.NoError(t, err)
assert.Equal(t, want[0].Vulnerabilities, got[0].Vulnerabilities)
assert.Equal(t, want[0].Vulnerabilities, got[0].Vulnerabilities)
})
}
}
func scan(imageRef name.Reference, baseDir string, opt registryOption) (string, error) {
// Copy DB file
cacheDir, err := gunzipDB()
if err != nil {
return "", err
}
defer os.RemoveAll(cacheDir)
// Setup the output file
var outputFile string
output, err := ioutil.TempFile("", "integration")
if err != nil {
return "", err
}
if err = output.Close(); err != nil {
return "", err
}
outputFile = output.Name()
// Setup env
if err = setupEnv(imageRef, baseDir, opt); err != nil {
return "", err
}
defer unsetEnv()
// Setup CLI App
app := internal.NewApp("dev")
app.Writer = ioutil.Discard
osArgs := []string{"trivy", "--cache-dir", cacheDir, "--format", "json", "--skip-update", "--output", outputFile, imageRef.Name()}
// Run Trivy
if err = app.Run(osArgs); err != nil {
return "", err
}
return outputFile, nil
}
func setupEnv(imageRef name.Reference, baseDir string, opt registryOption) error {
if err := os.Setenv("TRIVY_INSECURE", "true"); err != nil {
return err
}
if opt.Username != "" && opt.Password != "" {
if opt.RegistryToken {
// Get a registry token in advance
token, err := requestRegistryToken(imageRef, baseDir, opt)
if err != nil {
return err
}
if err := os.Setenv("TRIVY_REGISTRY_TOKEN", token); err != nil {
return err
}
} else {
if err := os.Setenv("TRIVY_USERNAME", opt.Username); err != nil {
return err
}
if err := os.Setenv("TRIVY_PASSWORD", opt.Password); err != nil {
return err
}
}
}
return nil
}
func unsetEnv() error {
envs := []string{"TRIVY_INSECURE", "TRIVY_USERNAME", "TRIVY_PASSWORD", "TRIVY_REGISTRY_TOKEN"}
for _, e := range envs {
if err := os.Unsetenv(e); err != nil {
return err
}
}
return nil
}
func requestRegistryToken(imageRef name.Reference, baseDir string, opt registryOption) (string, error) {
// Create a CA certificate pool and add cert.pem to it
caCert, err := ioutil.ReadFile(filepath.Join(baseDir, "data", "certs", "cert.pem"))
if err != nil {
return "", err
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Create a HTTPS client and supply the created CA pool
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: caCertPool,
},
},
}
// Get a registry token
req, err := http.NewRequest("GET", fmt.Sprintf("%s/auth", opt.AuthURL), nil)
if err != nil {
return "", err
}
// Set query parameters
values := req.URL.Query()
values.Set("service", "registry.docker.io")
values.Set("scope", imageRef.Scope("pull"))
req.URL.RawQuery = values.Encode()
req.SetBasicAuth(opt.Username, opt.Password)
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
type res struct {
AccessToken string `json:"access_token"`
}
var r res
if err = json.NewDecoder(resp.Body).Decode(&r); err != nil {
return "", err
}
return r.AccessToken, nil
}

View File

@@ -16,13 +16,14 @@ import (
func TestRun_WithTar(t *testing.T) {
type args struct {
Version string
SkipUpdate bool
IgnoreUnfixed bool
Severity []string
IgnoreIDs []string
Format string
Input string
Version string
WithImageSubcommand bool
SkipUpdate bool
IgnoreUnfixed bool
Severity []string
IgnoreIDs []string
Format string
Input string
}
cases := []struct {
name string
@@ -39,6 +40,17 @@ func TestRun_WithTar(t *testing.T) {
},
golden: "testdata/alpine-310.json.golden",
},
{
name: "alpine 3.10 integration with image subcommand",
testArgs: args{
Version: "dev",
WithImageSubcommand: true,
SkipUpdate: true,
Format: "json",
Input: "testdata/fixtures/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.json.golden",
},
{
name: "alpine 3.10 integration with --ignore-unfixed option",
testArgs: args{
@@ -354,7 +366,13 @@ func TestRun_WithTar(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
osArgs := []string{"trivy", "--cache-dir", cacheDir, "--format", c.testArgs.Format}
osArgs := []string{"trivy"}
osArgs = append(osArgs, "--cache-dir", cacheDir)
if c.testArgs.WithImageSubcommand {
osArgs = append(osArgs, "image")
}
osArgs = append(osArgs, "--format", c.testArgs.Format)
if c.testArgs.SkipUpdate {
osArgs = append(osArgs, "--skip-update")
}

View File

@@ -0,0 +1,107 @@
[
{
"Target": "localhost:5000/alpine:3.10 (alpine 3.10.2)",
"Type": "alpine",
"Vulnerabilities": [
{
"VulnerabilityID": "CVE-2019-1549",
"PkgName": "openssl",
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r0",
"Layer": {
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0",
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609"
},
"SeveritySource": "nvd",
"Title": "openssl: information disclosure in fork()",
"Description": "OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).",
"Severity": "MEDIUM",
"References": [
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=1b0fe00e2704b5e20334a16d3c9099d1ba2ef1be",
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/GY6SNRJP2S7Y42GIIDO3HXPNMDYN2U3A/",
"https://security.netapp.com/advisory/ntap-20190919-0002/",
"https://support.f5.com/csp/article/K44070243",
"https://www.openssl.org/news/secadv/20190910.txt"
]
},
{
"VulnerabilityID": "CVE-2019-1551",
"PkgName": "openssl",
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r2",
"Layer": {
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0",
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609"
},
"SeveritySource": "nvd",
"Title": "openssl: Integer overflow in RSAZ modular exponentiation on x86_64",
"Description": "There is an overflow bug in the x64_64 Montgomery squaring procedure used in exponentiation with 512-bit moduli. No EC algorithms are affected. Analysis suggests that attacks against 2-prime RSA1024, 3-prime RSA1536, and DSA1024 as a result of this defect would be very difficult to perform and are not believed likely. Attacks against DH512 are considered just feasible. However, for an attack the target would have to re-use the DH512 private key, which is not recommended anyway. Also applications directly using the low level API BN_mod_exp may be affected if they use BN_FLG_CONSTTIME. Fixed in OpenSSL 1.1.1e (Affected 1.1.1-1.1.1d). Fixed in OpenSSL 1.0.2u (Affected 1.0.2-1.0.2t).",
"Severity": "MEDIUM",
"References": [
"http://lists.opensuse.org/opensuse-security-announce/2020-01/msg00030.html",
"http://packetstormsecurity.com/files/155754/Slackware-Security-Advisory-openssl-Updates.html",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1551",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=419102400a2811582a7a3d4a4e317d72e5ce0a8f",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=f1c5eea8a817075d31e43f5876993c6710238c98",
"https://github.com/openssl/openssl/pull/10575",
"https://seclists.org/bugtraq/2019/Dec/39",
"https://seclists.org/bugtraq/2019/Dec/46",
"https://security.netapp.com/advisory/ntap-20191210-0001/",
"https://www.debian.org/security/2019/dsa-4594",
"https://www.openssl.org/news/secadv/20191206.txt",
"https://www.tenable.com/security/tns-2019-09"
]
},
{
"VulnerabilityID": "CVE-2019-1563",
"PkgName": "openssl",
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r0",
"Layer": {
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0",
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609"
},
"SeveritySource": "nvd",
"Title": "openssl: information disclosure in PKCS7_dataDecode and CMS_decrypt_set1_pkey",
"Description": "In situations where an attacker receives automated notification of the success or failure of a decryption attempt an attacker, after sending a very large number of messages to be decrypted, can recover a CMS/PKCS7 transported encryption key or decrypt any RSA encrypted message that was encrypted with the public RSA key, using a Bleichenbacher padding oracle attack. Applications are not affected if they use a certificate together with the private RSA key to the CMS_decrypt or PKCS7_decrypt functions to select the correct recipient info to decrypt. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). Fixed in OpenSSL 1.1.0l (Affected 1.1.0-1.1.0k). Fixed in OpenSSL 1.0.2t (Affected 1.0.2-1.0.2s).",
"Severity": "MEDIUM",
"References": [
"http://packetstormsecurity.com/files/154467/Slackware-Security-Advisory-openssl-Updates.html",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1563",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=08229ad838c50f644d7e928e2eef147b4308ad64",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=631f94db0065c78181ca9ba5546ebc8bb3884b97",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=e21f8cf78a125cd3c8c0d1a1a6c8bb0b901f893f",
"https://seclists.org/bugtraq/2019/Sep/25",
"https://security.netapp.com/advisory/ntap-20190919-0002/",
"https://www.openssl.org/news/secadv/20190910.txt"
]
},
{
"VulnerabilityID": "CVE-2019-1547",
"PkgName": "openssl",
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r0",
"Layer": {
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0",
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609"
},
"SeveritySource": "nvd",
"Title": "openssl: side-channel weak encryption vulnerability",
"Description": "Normally in OpenSSL EC groups always have a co-factor present and this is used in side channel resistant code paths. However, in some cases, it is possible to construct a group using explicit parameters (instead of using a named curve). In those cases it is possible that such a group does not have the cofactor present. This can occur even where all the parameters match a known named curve. If such a curve is used then OpenSSL falls back to non-side channel resistant code paths which may result in full key recovery during an ECDSA signature operation. In order to be vulnerable an attacker would have to have the ability to time the creation of a large number of signatures where explicit parameters with no co-factor present are in use by an application using libcrypto. For the avoidance of doubt libssl is not vulnerable because explicit parameters are never used. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c). Fixed in OpenSSL 1.1.0l (Affected 1.1.0-1.1.0k). Fixed in OpenSSL 1.0.2t (Affected 1.0.2-1.0.2s).",
"Severity": "LOW",
"References": [
"http://packetstormsecurity.com/files/154467/Slackware-Security-Advisory-openssl-Updates.html",
"https://arxiv.org/abs/1909.01785",
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=21c856b75d81eff61aa63b4f036bb64a85bf6d46",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=30c22fa8b1d840036b8e203585738df62a03cec8",
"https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=7c1709c2da5414f5b6133d00a03fc8c5bf996c7a",
"https://seclists.org/bugtraq/2019/Sep/25",
"https://security.netapp.com/advisory/ntap-20190919-0002/",
"https://www.openssl.org/news/secadv/20190910.txt"
]
}
]
}
]

View File

@@ -8,7 +8,7 @@ import (
"time"
"github.com/spf13/afero"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy-db/pkg/types"
@@ -27,164 +27,202 @@ type VersionInfo struct {
var (
templateFlag = cli.StringFlag{
Name: "template, t",
Value: "",
Usage: "output template",
EnvVar: "TRIVY_TEMPLATE",
Name: "template",
Aliases: []string{"t"},
Value: "",
Usage: "output template",
EnvVars: []string{"TRIVY_TEMPLATE"},
}
formatFlag = cli.StringFlag{
Name: "format, f",
Value: "table",
Usage: "format (table, json, template)",
EnvVar: "TRIVY_FORMAT",
Name: "format",
Aliases: []string{"f"},
Value: "table",
Usage: "format (table, json, template)",
EnvVars: []string{"TRIVY_FORMAT"},
}
inputFlag = cli.StringFlag{
Name: "input, i",
Value: "",
Usage: "input file path instead of image name",
EnvVar: "TRIVY_INPUT",
Name: "input",
Aliases: []string{"i"},
Value: "",
Usage: "input file path instead of image name",
EnvVars: []string{"TRIVY_INPUT"},
}
severityFlag = cli.StringFlag{
Name: "severity, s",
Value: strings.Join(types.SeverityNames, ","),
Usage: "severities of vulnerabilities to be displayed (comma separated)",
EnvVar: "TRIVY_SEVERITY",
Name: "severity",
Aliases: []string{"s"},
Value: strings.Join(types.SeverityNames, ","),
Usage: "severities of vulnerabilities to be displayed (comma separated)",
EnvVars: []string{"TRIVY_SEVERITY"},
}
outputFlag = cli.StringFlag{
Name: "output, o",
Usage: "output file name",
EnvVar: "TRIVY_OUTPUT",
Name: "output",
Aliases: []string{"o"},
Usage: "output file name",
EnvVars: []string{"TRIVY_OUTPUT"},
}
exitCodeFlag = cli.IntFlag{
Name: "exit-code",
Usage: "Exit code when vulnerabilities were found",
Value: 0,
EnvVar: "TRIVY_EXIT_CODE",
Name: "exit-code",
Usage: "Exit code when vulnerabilities were found",
Value: 0,
EnvVars: []string{"TRIVY_EXIT_CODE"},
}
skipUpdateFlag = cli.BoolFlag{
Name: "skip-update",
Usage: "skip db update",
EnvVar: "TRIVY_SKIP_UPDATE",
Name: "skip-update",
Usage: "skip db update",
EnvVars: []string{"TRIVY_SKIP_UPDATE"},
}
downloadDBOnlyFlag = cli.BoolFlag{
Name: "download-db-only",
Usage: "download/update vulnerability database but don't run a scan",
EnvVar: "TRIVY_DOWNLOAD_DB_ONLY",
Name: "download-db-only",
Usage: "download/update vulnerability database but don't run a scan",
EnvVars: []string{"TRIVY_DOWNLOAD_DB_ONLY"},
}
resetFlag = cli.BoolFlag{
Name: "reset",
Usage: "remove all caches and database",
EnvVar: "TRIVY_RESET",
Name: "reset",
Usage: "remove all caches and database",
EnvVars: []string{"TRIVY_RESET"},
}
clearCacheFlag = cli.BoolFlag{
Name: "clear-cache, c",
Usage: "clear image caches without scanning",
EnvVar: "TRIVY_CLEAR_CACHE",
Name: "clear-cache",
Aliases: []string{"c"},
Usage: "clear image caches without scanning",
EnvVars: []string{"TRIVY_CLEAR_CACHE"},
}
quietFlag = cli.BoolFlag{
Name: "quiet, q",
Usage: "suppress progress bar and log output",
EnvVar: "TRIVY_QUIET",
Name: "quiet",
Aliases: []string{"q"},
Usage: "suppress progress bar and log output",
EnvVars: []string{"TRIVY_QUIET"},
}
noProgressFlag = cli.BoolFlag{
Name: "no-progress",
Usage: "suppress progress bar",
EnvVar: "TRIVY_NO_PROGRESS",
Name: "no-progress",
Usage: "suppress progress bar",
EnvVars: []string{"TRIVY_NO_PROGRESS"},
}
ignoreUnfixedFlag = cli.BoolFlag{
Name: "ignore-unfixed",
Usage: "display only fixed vulnerabilities",
EnvVar: "TRIVY_IGNORE_UNFIXED",
Name: "ignore-unfixed",
Usage: "display only fixed vulnerabilities",
EnvVars: []string{"TRIVY_IGNORE_UNFIXED"},
}
debugFlag = cli.BoolFlag{
Name: "debug, d",
Usage: "debug mode",
EnvVar: "TRIVY_DEBUG",
Name: "debug",
Aliases: []string{"d"},
Usage: "debug mode",
EnvVars: []string{"TRIVY_DEBUG"},
}
removedPkgsFlag = cli.BoolFlag{
Name: "removed-pkgs",
Usage: "detect vulnerabilities of removed packages (only for Alpine)",
EnvVar: "TRIVY_REMOVED_PKGS",
Name: "removed-pkgs",
Usage: "detect vulnerabilities of removed packages (only for Alpine)",
EnvVars: []string{"TRIVY_REMOVED_PKGS"},
}
vulnTypeFlag = cli.StringFlag{
Name: "vuln-type",
Value: "os,library",
Usage: "comma-separated list of vulnerability types (os,library)",
EnvVar: "TRIVY_VULN_TYPE",
Name: "vuln-type",
Value: "os,library",
Usage: "comma-separated list of vulnerability types (os,library)",
EnvVars: []string{"TRIVY_VULN_TYPE"},
}
cacheDirFlag = cli.StringFlag{
Name: "cache-dir",
Value: utils.DefaultCacheDir(),
Usage: "cache directory",
EnvVar: "TRIVY_CACHE_DIR",
Name: "cache-dir",
Value: utils.DefaultCacheDir(),
Usage: "cache directory",
EnvVars: []string{"TRIVY_CACHE_DIR"},
}
ignoreFileFlag = cli.StringFlag{
Name: "ignorefile",
Value: vulnerability.DefaultIgnoreFile,
Usage: "specify .trivyignore file",
EnvVar: "TRIVY_IGNOREFILE",
Name: "ignorefile",
Value: vulnerability.DefaultIgnoreFile,
Usage: "specify .trivyignore file",
EnvVars: []string{"TRIVY_IGNOREFILE"},
}
timeoutFlag = cli.DurationFlag{
Name: "timeout",
Value: time.Second * 120,
Usage: "docker timeout",
EnvVar: "TRIVY_TIMEOUT",
Name: "timeout",
Value: time.Second * 120,
Usage: "docker timeout",
EnvVars: []string{"TRIVY_TIMEOUT"},
}
lightFlag = cli.BoolFlag{
Name: "light",
Usage: "light mode: it's faster, but vulnerability descriptions and references are not displayed",
EnvVar: "TRIVY_LIGHT",
Name: "light",
Usage: "light mode: it's faster, but vulnerability descriptions and references are not displayed",
EnvVars: []string{"TRIVY_LIGHT"},
}
token = cli.StringFlag{
Name: "token",
Usage: "for authentication",
EnvVar: "TRIVY_TOKEN",
Name: "token",
Usage: "for authentication",
EnvVars: []string{"TRIVY_TOKEN"},
}
tokenHeader = cli.StringFlag{
Name: "token-header",
Value: "Trivy-Token",
Usage: "specify a header name for token",
EnvVar: "TRIVY_TOKEN_HEADER",
Name: "token-header",
Value: "Trivy-Token",
Usage: "specify a header name for token",
EnvVars: []string{"TRIVY_TOKEN_HEADER"},
}
globalFlags = []cli.Flag{
&quietFlag,
&debugFlag,
&cacheDirFlag,
}
imageFlags = []cli.Flag{
&templateFlag,
&formatFlag,
&inputFlag,
&severityFlag,
&outputFlag,
&exitCodeFlag,
&skipUpdateFlag,
&downloadDBOnlyFlag,
&resetFlag,
&clearCacheFlag,
&noProgressFlag,
&ignoreUnfixedFlag,
&removedPkgsFlag,
&vulnTypeFlag,
&ignoreFileFlag,
&timeoutFlag,
&lightFlag,
}
// deprecated options
deprecatedFlags = []cli.Flag{
&cli.StringFlag{
Name: "only-update",
Usage: "deprecated",
EnvVars: []string{"TRIVY_ONLY_UPDATE"},
},
&cli.BoolFlag{
Name: "refresh",
Usage: "deprecated",
EnvVars: []string{"TRIVY_REFRESH"},
},
&cli.BoolFlag{
Name: "auto-refresh",
Usage: "deprecated",
EnvVars: []string{"TRIVY_AUTO_REFRESH"},
},
}
)
func NewApp(version string) *cli.App {
cli.AppHelpTemplate = `NAME:
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
USAGE:
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
VERSION:
{{.Version}}{{end}}{{end}}{{if .Description}}
DESCRIPTION:
{{.Description}}{{end}}{{if len .Authors}}
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
{{range $index, $author := .Authors}}{{if $index}}
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
OPTIONS:
{{range $index, $option := .VisibleFlags}}{{if $index}}
{{end}}{{$option}}{{end}}{{end}}
`
cli.VersionPrinter = func(c *cli.Context) {
showVersion(c.String("cache-dir"), c.String("format"), c.App.Version, c.App.Writer)
}
@@ -193,60 +231,49 @@ OPTIONS:
app.Name = "trivy"
app.Version = version
app.ArgsUsage = "image_name"
app.Usage = "A simple and comprehensive vulnerability scanner for containers"
app.EnableBashCompletion = true
app.Flags = []cli.Flag{
templateFlag,
formatFlag,
inputFlag,
severityFlag,
outputFlag,
exitCodeFlag,
skipUpdateFlag,
downloadDBOnlyFlag,
resetFlag,
clearCacheFlag,
quietFlag,
noProgressFlag,
ignoreUnfixedFlag,
debugFlag,
removedPkgsFlag,
vulnTypeFlag,
cacheDirFlag,
ignoreFileFlag,
timeoutFlag,
lightFlag,
flags := append(globalFlags, setHidden(deprecatedFlags, true)...)
flags = append(flags, setHidden(imageFlags, true)...)
// deprecated options
cli.StringFlag{
Name: "only-update",
Usage: "deprecated",
EnvVar: "TRIVY_ONLY_UPDATE",
},
cli.BoolFlag{
Name: "refresh",
Usage: "deprecated",
EnvVar: "TRIVY_REFRESH",
},
cli.BoolFlag{
Name: "auto-refresh",
Usage: "deprecated",
EnvVar: "TRIVY_AUTO_REFRESH",
},
}
app.Commands = []cli.Command{
app.Flags = flags
app.Commands = []*cli.Command{
NewImageCommand(),
NewClientCommand(),
NewServerCommand(),
}
app.Action = standalone.Run
return app
}
func setHidden(flags []cli.Flag, hidden bool) []cli.Flag {
var newFlags []cli.Flag
for _, flag := range flags {
var f cli.Flag
switch pf := flag.(type) {
case *cli.StringFlag:
stringFlag := *pf
stringFlag.Hidden = hidden
f = &stringFlag
case *cli.BoolFlag:
boolFlag := *pf
boolFlag.Hidden = hidden
f = &boolFlag
case *cli.IntFlag:
intFlag := *pf
intFlag.Hidden = hidden
f = &intFlag
case *cli.DurationFlag:
durationFlag := *pf
durationFlag.Hidden = hidden
f = &durationFlag
}
newFlags = append(newFlags, f)
}
return newFlags
}
func showVersion(cacheDir, outputFormat, version string, outputWriter io.Writer) {
var dbMeta *db.Metadata
@@ -288,69 +315,79 @@ func showVersion(cacheDir, outputFormat, version string, outputWriter io.Writer)
}
}
func NewClientCommand() cli.Command {
return cli.Command{
func NewImageCommand() *cli.Command {
return &cli.Command{
Name: "image",
Aliases: []string{"i"},
Usage: "scan an image",
Action: standalone.Run,
Flags: imageFlags,
}
}
func NewClientCommand() *cli.Command {
return &cli.Command{
Name: "client",
Aliases: []string{"c"},
Usage: "client mode",
Action: client.Run,
Flags: []cli.Flag{
templateFlag,
formatFlag,
inputFlag,
severityFlag,
outputFlag,
exitCodeFlag,
clearCacheFlag,
quietFlag,
ignoreUnfixedFlag,
debugFlag,
removedPkgsFlag,
vulnTypeFlag,
ignoreFileFlag,
cacheDirFlag,
timeoutFlag,
&templateFlag,
&formatFlag,
&inputFlag,
&severityFlag,
&outputFlag,
&exitCodeFlag,
&clearCacheFlag,
&quietFlag,
&ignoreUnfixedFlag,
&debugFlag,
&removedPkgsFlag,
&vulnTypeFlag,
&ignoreFileFlag,
&cacheDirFlag,
&timeoutFlag,
// original flags
token,
tokenHeader,
cli.StringFlag{
Name: "remote",
Value: "http://localhost:4954",
Usage: "server address",
EnvVar: "TRIVY_REMOTE",
&token,
&tokenHeader,
&cli.StringFlag{
Name: "remote",
Value: "http://localhost:4954",
Usage: "server address",
EnvVars: []string{"TRIVY_REMOTE"},
},
cli.StringSliceFlag{
Name: "custom-headers",
Usage: "custom headers",
EnvVar: "TRIVY_CUSTOM_HEADERS",
&cli.StringSliceFlag{
Name: "custom-headers",
Usage: "custom headers",
EnvVars: []string{"TRIVY_CUSTOM_HEADERS"},
},
},
}
}
func NewServerCommand() cli.Command {
return cli.Command{
func NewServerCommand() *cli.Command {
return &cli.Command{
Name: "server",
Aliases: []string{"s"},
Usage: "server mode",
Action: server.Run,
Flags: []cli.Flag{
skipUpdateFlag,
downloadDBOnlyFlag,
resetFlag,
quietFlag,
debugFlag,
cacheDirFlag,
&skipUpdateFlag,
&downloadDBOnlyFlag,
&resetFlag,
&quietFlag,
&debugFlag,
&cacheDirFlag,
// original flags
token,
tokenHeader,
cli.StringFlag{
Name: "listen",
Value: "localhost:4954",
Usage: "listen address",
EnvVar: "TRIVY_LISTEN",
&token,
&tokenHeader,
&cli.StringFlag{
Name: "listen",
Value: "localhost:4954",
Usage: "listen address",
EnvVars: []string{"TRIVY_LISTEN"},
},
},
}

View File

@@ -7,7 +7,7 @@ import (
"time"
"github.com/genuinetools/reg/registry"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"golang.org/x/xerrors"
@@ -105,12 +105,12 @@ func (c *Config) Init() (err error) {
return nil
}
args := c.context.Args()
if c.Input == "" && len(args) == 0 {
ctx := c.context
if c.Input == "" && ctx.NArg() == 0 {
c.logger.Error(`trivy requires at least 1 argument or --input option`)
cli.ShowAppHelp(c.context)
return xerrors.New("arguments error")
} else if len(args) > 1 {
} else if ctx.NArg() > 1 {
c.logger.Error(`multiple images cannot be specified`)
return xerrors.New("arguments error")
}
@@ -123,7 +123,7 @@ func (c *Config) Init() (err error) {
}
if c.Input == "" {
c.ImageName = args[0]
c.ImageName = ctx.Args().First()
}
// Check whether 'latest' tag is used

View File

@@ -8,14 +8,13 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"go.uber.org/zap/zaptest/observer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
)
func TestNew(t *testing.T) {
@@ -107,7 +106,6 @@ func TestConfig_Init(t *testing.T) {
},
args: []string{"alpine:3.10"},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
severities: "CRITICAL",
ImageName: "alpine:3.10",
@@ -133,7 +131,6 @@ func TestConfig_Init(t *testing.T) {
"unknown severity option: unknown severity: INVALID",
},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityCritical, dbTypes.SeverityUnknown},
severities: "CRITICAL,INVALID",
ImageName: "centos:7",
@@ -155,7 +152,6 @@ func TestConfig_Init(t *testing.T) {
"You should avoid using the :latest tag as it is cached. You need to specify '--clear-cache' option when :latest image is changed",
},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
severities: "LOW",
ImageName: "gcr.io/distroless/base",

View File

@@ -4,6 +4,9 @@ import (
"context"
"os"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/internal/client/config"
"github.com/aquasecurity/trivy/pkg/cache"
"github.com/aquasecurity/trivy/pkg/log"
@@ -12,8 +15,6 @@ import (
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
"github.com/urfave/cli"
"golang.org/x/xerrors"
)
func Run(cliCtx *cli.Context) error {

View File

@@ -1,7 +1,7 @@
package config
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
)

View File

@@ -6,10 +6,11 @@ import (
"testing"
"time"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
)
func TestNew(t *testing.T) {
@@ -95,8 +96,7 @@ func TestConfig_Init(t *testing.T) {
},
args: []string{"alpine:3.10"},
want: Config{
AppVersion: "0.0.0",
Quiet: true,
Quiet: true,
},
},
{
@@ -108,8 +108,7 @@ func TestConfig_Init(t *testing.T) {
},
args: []string{"alpine:3.10"},
want: Config{
AppVersion: "0.0.0",
Reset: true,
Reset: true,
},
},
{

View File

@@ -1,7 +1,7 @@
package server
import (
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/fanal/cache"

View File

@@ -6,7 +6,7 @@ import (
"time"
"github.com/genuinetools/reg/registry"
"github.com/urfave/cli"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"golang.org/x/xerrors"
@@ -125,12 +125,12 @@ func (c *Config) Init() (err error) {
return nil
}
args := c.context.Args()
if c.Input == "" && len(args) == 0 {
ctx := c.context
if c.Input == "" && ctx.NArg() == 0 {
c.logger.Error(`trivy requires at least 1 argument or --input option`)
cli.ShowAppHelp(c.context)
return xerrors.New("arguments error")
} else if len(args) > 1 {
} else if ctx.NArg() > 1 {
c.logger.Error(`multiple images cannot be specified`)
return xerrors.New("arguments error")
}
@@ -143,7 +143,7 @@ func (c *Config) Init() (err error) {
}
if c.Input == "" {
c.ImageName = args[0]
c.ImageName = ctx.Args().First()
}
// Check whether 'latest' tag is used

View File

@@ -6,12 +6,12 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
"go.uber.org/zap/zaptest/observer"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
)
func TestNew(t *testing.T) {
@@ -45,8 +45,14 @@ func TestNew(t *testing.T) {
tt.want.context = c
_, err := New(c)
config, err := New(c)
assert.NoError(t, err, tt.name)
assert.Equal(t, tt.want.Quiet, config.Quiet, tt.name)
assert.Equal(t, tt.want.NoProgress, config.NoProgress, tt.name)
assert.Equal(t, tt.want.Reset, config.Reset, tt.name)
assert.Equal(t, tt.want.SkipUpdate, config.SkipUpdate, tt.name)
})
}
}
@@ -99,7 +105,6 @@ func TestConfig_Init(t *testing.T) {
},
args: []string{"alpine:3.10"},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
severities: "CRITICAL",
ImageName: "alpine:3.10",
@@ -118,7 +123,6 @@ func TestConfig_Init(t *testing.T) {
},
args: []string{"alpine:3.10"},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityCritical},
severities: "CRITICAL",
VulnType: []string{"os"},
@@ -137,7 +141,6 @@ func TestConfig_Init(t *testing.T) {
"unknown severity option: unknown severity: INVALID",
},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityCritical, dbTypes.SeverityUnknown},
severities: "CRITICAL,INVALID",
ImageName: "centos:7",
@@ -158,7 +161,6 @@ func TestConfig_Init(t *testing.T) {
"--only-update, --refresh and --auto-refresh are unnecessary and ignored now. These commands will be removed in the next version.",
},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
severities: "LOW",
ImageName: "debian:buster",
@@ -179,7 +181,6 @@ func TestConfig_Init(t *testing.T) {
"--template is ignored because --format template is not specified. Use --template option with --format template option.",
},
want: Config{
AppVersion: "0.0.0",
ImageName: "gitlab/gitlab-ce:12.7.2-ce.0",
Output: os.Stdout,
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
@@ -200,7 +201,6 @@ func TestConfig_Init(t *testing.T) {
"--template is ignored because --format json is specified. Use --template option with --format template option.",
},
want: Config{
AppVersion: "0.0.0",
Format: "json",
ImageName: "gitlab/gitlab-ce:12.7.2-ce.0",
Output: os.Stdout,
@@ -221,7 +221,6 @@ func TestConfig_Init(t *testing.T) {
"--format template is ignored because --template not is specified. Specify --template option when you use --format template.",
},
want: Config{
AppVersion: "0.0.0",
Format: "template",
ImageName: "gitlab/gitlab-ce:12.7.2-ce.0",
Output: os.Stdout,
@@ -243,7 +242,6 @@ func TestConfig_Init(t *testing.T) {
"You should avoid using the :latest tag as it is cached. You need to specify '--clear-cache' option when :latest image is changed",
},
want: Config{
AppVersion: "0.0.0",
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
severities: "LOW",
ImageName: "gcr.io/distroless/base",

View File

@@ -5,9 +5,11 @@ import (
l "log"
"os"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/aquasecurity/fanal/cache"
"github.com/aquasecurity/trivy-db/pkg/db"
"github.com/aquasecurity/trivy/internal/operation"
"github.com/aquasecurity/trivy/internal/standalone/config"
"github.com/aquasecurity/trivy/pkg/log"
@@ -15,8 +17,6 @@ import (
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/utils"
"github.com/urfave/cli"
"golang.org/x/xerrors"
)
func Run(cliCtx *cli.Context) error {

View File

@@ -3,26 +3,30 @@ package types
import (
"time"
"github.com/aquasecurity/fanal/types"
"github.com/caarlos0/env/v6"
"golang.org/x/xerrors"
"github.com/aquasecurity/fanal/types"
)
type DockerConfig struct {
UserName string `env:"TRIVY_USERNAME"`
Password string `env:"TRIVY_PASSWORD"`
Insecure bool `env:"TRIVY_INSECURE" envDefault:"false"`
NonSSL bool `env:"TRIVY_NON_SSL" envDefault:"false"`
UserName string `env:"TRIVY_USERNAME"`
Password string `env:"TRIVY_PASSWORD"`
RegistryToken string `env:"TRIVY_REGISTRY_TOKEN"`
Insecure bool `env:"TRIVY_INSECURE" envDefault:"false"`
NonSSL bool `env:"TRIVY_NON_SSL" envDefault:"false"`
}
func GetDockerOption(timeout time.Duration) (types.DockerOption, error) {
cfg := DockerConfig{}
if err := env.Parse(&cfg); err != nil {
return types.DockerOption{}, err
return types.DockerOption{}, xerrors.Errorf("unable to parse environment variables: %w", err)
}
return types.DockerOption{
UserName: cfg.UserName,
Password: cfg.Password,
RegistryToken: cfg.RegistryToken,
Timeout: timeout,
InsecureSkipTLSVerify: cfg.Insecure,
NonSSL: cfg.NonSSL,

View File

@@ -60,7 +60,7 @@ func TestClient_FillInfo(t *testing.T) {
vulns: []types.DetectedVulnerability{
{VulnerabilityID: "CVE-2019-0001"},
},
reportType: vulnerability.Ubuntu,
reportType: vulnerability.RedHat,
},
expectedVulnerabilities: []types.DetectedVulnerability{
{
@@ -146,7 +146,7 @@ func TestClient_FillInfo(t *testing.T) {
},
},
{
name: "happy path, with only OS vulnerability, yes vendor severity",
name: "happy path, with only OS vulnerability, yes vendor severity, with both NVD and vendor vectors",
getVulnerability: []db.GetVulnerabilityExpectation{
{
Args: db.GetVulnerabilityArgs{
@@ -160,6 +160,16 @@ func TestClient_FillInfo(t *testing.T) {
VendorSeverity: dbTypes.VendorSeverity{
vulnerability.RedHat: dbTypes.SeverityLow, // CentOS uses RedHat
},
VendorVectors: map[string]dbTypes.CVSSVector{
vulnerability.Nvd: {
V2: "(AV:N/AC:L/Au:N/C:P/I:P/A:P)",
V3: "CVSS:3.0/PR:N/UI:N/S:U/C:H/I:H/A:H",
},
vulnerability.RedHat: {
V2: "AV:N/AC:M/Au:N/C:N/I:P/A:N",
V3: "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
},
},
References: []string{"http://example.com"},
},
},
@@ -179,6 +189,16 @@ func TestClient_FillInfo(t *testing.T) {
Description: "dos vulnerability",
Severity: dbTypes.SeverityLow.String(),
References: []string{"http://example.com"},
VendorVectors: map[string]dbTypes.CVSSVector{
vulnerability.Nvd: {
V2: "(AV:N/AC:L/Au:N/C:P/I:P/A:P)",
V3: "CVSS:3.0/PR:N/UI:N/S:U/C:H/I:H/A:H",
},
vulnerability.RedHat: {
V2: "AV:N/AC:M/Au:N/C:N/I:P/A:N",
V3: "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
},
},
},
SeveritySource: vulnerability.RedHat,
},