Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
073b315737 | ||
|
|
47c46fbe17 | ||
|
|
39572968bb | ||
|
|
4383764cae | ||
|
|
e0ef0563ce | ||
|
|
d9cf2c487d | ||
|
|
58bf4b21e7 | ||
|
|
e95c619eaa | ||
|
|
cd04c0bdb2 | ||
|
|
fd74926e76 | ||
|
|
f82ff5a4fd | ||
|
|
fa72bef8d4 | ||
|
|
2f7f1f8e83 | ||
|
|
90d083489b | ||
|
|
295cd29aeb | ||
|
|
1c844aad64 | ||
|
|
e0cd18e264 | ||
|
|
9f9faf2215 | ||
|
|
3907a60b33 | ||
|
|
e85e961af6 | ||
|
|
61cbae2697 | ||
|
|
2d512c5e47 | ||
|
|
936297a6b2 | ||
|
|
ad0f9e8cba |
@@ -1 +1,2 @@
|
||||
.circleci
|
||||
imgs
|
||||
|
||||
@@ -11,4 +11,4 @@ RUN apk --no-cache add ca-certificates git
|
||||
COPY --from=builder /trivy /usr/local/bin/trivy
|
||||
RUN chmod +x /usr/local/bin/trivy
|
||||
|
||||
CMD ["trivy"]
|
||||
ENTRYPOINT ["trivy"]
|
||||
|
||||
714
README.md
@@ -3,12 +3,16 @@
|
||||
[](https://github.com/knqyf263/trivy/releases/latest)
|
||||
[](https://circleci.com/gh/knqyf263/trivy)
|
||||
[](https://goreportcard.com/report/github.com/knqyf263/trivy)
|
||||
[](https://github.com/knqyf263/trivy/blob/master/LICENSE)
|
||||
[](https://www.gnu.org/licenses/agpl-3.0)
|
||||
|
||||
A Simple and Comprehensive Vulnerability Scanner for Containers, Compatible with CI
|
||||
|
||||
A Simple and Comprehensive Vulnerability Scanner for Containers, Suitable for CI
|
||||
|
||||
<img src="imgs/usage.gif" width="700">
|
||||
|
||||
<img src="imgs/usage1.png" width="600">
|
||||
<img src="imgs/usage2.png" width="600">
|
||||
|
||||
# Accuracy Comparison
|
||||
|
||||
The number of vulnerabilities detected on Alpine Linux (as of 2019/05/12)
|
||||
@@ -28,6 +32,8 @@ See [Comparison with other scanners](#comparison-with-other-scanners) for detail
|
||||
- [Binary (Including Windows)](#binary-including-windows)
|
||||
- [From source](#from-source)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Basic](#basic)
|
||||
- [Docker](#docker)
|
||||
- [Examples](#examples)
|
||||
- [Scan an image](#scan-an-image)
|
||||
- [Scan an image file](#scan-an-image-file)
|
||||
@@ -48,9 +54,10 @@ See [Comparison with other scanners](#comparison-with-other-scanners) for detail
|
||||
- [Usage](#usage)
|
||||
- [Comparison with other scanners](#comparison-with-other-scanners)
|
||||
- [Overview](#overview)
|
||||
- [vs Clair, Quay](#vs-clair-quay)
|
||||
- [Accuracy](#accuracy)
|
||||
- [vs Clair](#vs-clair)
|
||||
- [vs Anchore Engine](#vs-anchore-engine)
|
||||
- [vs Docker Hub, GCR](#vs-docker-hub-gcr)
|
||||
- [vs Quay, Docker Hub, GCR](#vs-quay-docker-hub-gcr)
|
||||
- [Q&A](#qa)
|
||||
- [Homebrew](#homebrew)
|
||||
- [Others](#others)
|
||||
@@ -59,7 +66,7 @@ See [Comparison with other scanners](#comparison-with-other-scanners) for detail
|
||||
|
||||
`Trivy` (`tri` pronounced like **tri**gger, `vy` pronounced like en**vy**) is a simple and comprehensive vulnerability scanner for containers.
|
||||
`Trivy` detects vulnerabilities of OS packages (Alpine, RHEL, CentOS, etc.) and application dependencies (Bundler, Composer, npm, yarn etc.).
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan. All you need to do for scanning is to specify a container image name.
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan. All you need to do for scanning is to specify an image name of container.
|
||||
|
||||
It is considered to be used in CI. Before pushing to a container registry, you can scan your local container image easily.
|
||||
See [here](#continuous-integration-ci) for details.
|
||||
@@ -71,14 +78,15 @@ See [here](#continuous-integration-ci) for details.
|
||||
- **Application dependencies** (Bundler, Composer, Pipenv, npm, yarn and Cargo)
|
||||
- Simple
|
||||
- Specify only an image name
|
||||
- See [Quick Start](#quick-start) and [Examples](#examples)
|
||||
- Easy installation
|
||||
- **No need for prerequirements** such as installation of DB, libraries, etc.
|
||||
- `apt-get install`, `yum install` and `brew install` is possible (See [Installation](#installation))
|
||||
- High accuracy
|
||||
- **Especially Alpine Linux and RHEL/CentOS** (See [Comparison with other scanners](#comparison-with-other-scanners))
|
||||
- Other OSes are also high
|
||||
- Continuous Integration
|
||||
- **Compatible with CI** such as Travis CI, CircleCI, Jenkins, etc.
|
||||
- DevSecOps
|
||||
- **Suitable for CI** such as Travis CI, CircleCI, Jenkins, etc.
|
||||
- See [CI Example](#continuous-integration-ci)
|
||||
|
||||
# Installation
|
||||
@@ -101,7 +109,7 @@ $ sudo yum -y install trivy
|
||||
or
|
||||
|
||||
```
|
||||
$ rpm -ivh https://github.com/knqyf263/trivy/releases/download/v0.0.12/trivy_0.0.12_Linux-64bit.rpm
|
||||
$ rpm -ivh https://github.com/knqyf263/trivy/releases/download/v0.0.15/trivy_0.0.15_Linux-64bit.rpm
|
||||
```
|
||||
|
||||
## Debian/Ubuntu
|
||||
@@ -113,7 +121,7 @@ CODE_NAME: wheezy, jessie, stretch, buster, trusty, xenial, bionic
|
||||
```
|
||||
$ sudo apt-get install apt-transport-https gnupg
|
||||
$ wget -qO - https://knqyf263.github.io/trivy-repo/deb/public.key | sudo apt-key add -
|
||||
$ echo deb https://knqyf263.github.io/trivy-repo/deb [CODE_NAME] main | sudo tee -a /etc/apt/sources.list
|
||||
$ echo deb https://knqyf263.github.io/trivy-repo/deb [CODE_NAME] main | sudo tee -a /etc/apt/sources.list.d/trivy.list
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install trivy
|
||||
```
|
||||
@@ -122,13 +130,13 @@ or
|
||||
|
||||
```
|
||||
$ sudo apt-get install rpm
|
||||
$ wget https://github.com/knqyf263/trivy/releases/download/v0.0.12/trivy_0.0.12_Linux-64bit.deb
|
||||
$ sudo dpkg -i trivy_0.0.12_Linux-64bit.deb
|
||||
$ wget https://github.com/knqyf263/trivy/releases/download/v0.0.15/trivy_0.0.15_Linux-64bit.deb
|
||||
$ sudo dpkg -i trivy_0.0.15_Linux-64bit.deb
|
||||
```
|
||||
|
||||
## Mac OS X / Homebrew
|
||||
|
||||
You can use homebrew on OS X.
|
||||
You can use homebrew on Mac OS.
|
||||
|
||||
```
|
||||
$ brew tap knqyf263/trivy
|
||||
@@ -137,7 +145,7 @@ $ brew install knqyf263/trivy/trivy
|
||||
|
||||
## Binary (Including Windows)
|
||||
|
||||
Go to [the releases page](https://github.com/knqyf263/trivy/releases), find the version you want, and download the zip file. Unpack the zip file, and put the binary to somewhere you want (on UNIX-y systems, /usr/local/bin or the like). Make sure it has execution bits turned on.
|
||||
Get the latest version from [this page](https://github.com/knqyf263/trivy/releases/latest), and download the archive file for your operating system/architecture. Unpack the archive, and put the binary somewhere in your `$PATH` (on UNIX-y systems, /usr/local/bin or the like). Make sure it has execution bits turned on.
|
||||
|
||||
You need to install `rpm` command for scanning RHEL/CentOS.
|
||||
|
||||
@@ -147,11 +155,12 @@ You need to install `rpm` command for scanning RHEL/CentOS.
|
||||
$ go get -u github.com/knqyf263/trivy
|
||||
```
|
||||
|
||||
|
||||
# Quick Start
|
||||
|
||||
Simply specify an image name (and a tag). **The `latest` tag should be avoided as problems occur with cache.**. See [Clear image caches](#clear-image-caches)
|
||||
|
||||
## Basic
|
||||
|
||||
```
|
||||
$ trivy [YOUR_IMAGE_NAME]
|
||||
```
|
||||
@@ -159,16 +168,7 @@ $ trivy [YOUR_IMAGE_NAME]
|
||||
For example:
|
||||
|
||||
```
|
||||
$ trivy python:3.7-alpine
|
||||
```
|
||||
|
||||
# Examples
|
||||
|
||||
### Scan an image
|
||||
Simply specify an image name (and a tag).
|
||||
|
||||
```
|
||||
$ trivy python:3.7-alpine
|
||||
$ trivy python:3.4-alpine
|
||||
```
|
||||
|
||||
<details>
|
||||
@@ -192,6 +192,264 @@ Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
</details>
|
||||
|
||||
## Docker
|
||||
|
||||
Replace [YOUR_CACHE_DIR] with the cache directory on your machine.
|
||||
|
||||
```
|
||||
$ docker run -v [YOUR_CACHE_DIR]:/root/.cache/ knqyf263/trivy [YOUR_IMAGE_NAME]
|
||||
```
|
||||
|
||||
Example for macOS:
|
||||
|
||||
```
|
||||
$ docker run -v $HOME/Library/Caches:/root/.cache/ knqyf263/trivy python:3.4-alpine
|
||||
```
|
||||
|
||||
If you would like to scan the image on your host machine, you need to mount `docker.sock`.
|
||||
|
||||
```
|
||||
$ docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ knqyf263/trivy python:3.4-alpine
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T01:20:43.180+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T01:20:53.029+0900 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
python:3.4-alpine3.9 (alpine 3.9.2)
|
||||
===================================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
|
||||
| | | | | | with long nonces |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
# Examples
|
||||
|
||||
### Scan an image
|
||||
|
||||
Simply specify an image name (and a tag).
|
||||
|
||||
```
|
||||
$ trivy knqyf263/test-image:1.2.3
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T12:58:55.967+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T12:59:03.150+0900 INFO Detecting Alpine vulnerabilities...
|
||||
2019-05-16T12:59:03.156+0900 INFO Updating bundler Security DB...
|
||||
2019-05-16T12:59:04.941+0900 INFO Detecting bundler vulnerabilities...
|
||||
2019-05-16T12:59:04.942+0900 INFO Updating cargo Security DB...
|
||||
2019-05-16T12:59:05.967+0900 INFO Detecting cargo vulnerabilities...
|
||||
2019-05-16T12:59:05.967+0900 INFO Updating composer Security DB...
|
||||
2019-05-16T12:59:07.834+0900 INFO Detecting composer vulnerabilities...
|
||||
2019-05-16T12:59:07.834+0900 INFO Updating npm Security DB...
|
||||
2019-05-16T12:59:10.285+0900 INFO Detecting npm vulnerabilities...
|
||||
2019-05-16T12:59:10.285+0900 INFO Updating pipenv Security DB...
|
||||
2019-05-16T12:59:11.487+0900 INFO Detecting pipenv vulnerabilities...
|
||||
|
||||
knqyf263/test-image:1.2.3 (alpine 3.7.1)
|
||||
========================================
|
||||
Total: 26 (UNKNOWN: 0, LOW: 3, MEDIUM: 16, HIGH: 5, CRITICAL: 2)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
| curl | CVE-2018-14618 | CRITICAL | 7.61.0-r0 | 7.61.1-r0 | curl: NTLM password overflow |
|
||||
| | | | | | via integer overflow |
|
||||
+ +------------------+----------+ +---------------+----------------------------------+
|
||||
| | CVE-2018-16839 | HIGH | | 7.61.1-r1 | curl: Integer overflow leading |
|
||||
| | | | | | to heap-based buffer overflow in |
|
||||
| | | | | | Curl_sasl_create_plain_message() |
|
||||
+ +------------------+ + +---------------+----------------------------------+
|
||||
| | CVE-2019-3822 | | | 7.61.1-r2 | curl: NTLMv2 type-3 header |
|
||||
| | | | | | stack buffer overflow |
|
||||
+ +------------------+ + +---------------+----------------------------------+
|
||||
| | CVE-2018-16840 | | | 7.61.1-r1 | curl: Use-after-free when |
|
||||
| | | | | | closing "easy" handle in |
|
||||
| | | | | | Curl_close() |
|
||||
+ +------------------+----------+ + +----------------------------------+
|
||||
| | CVE-2018-16842 | MEDIUM | | | curl: Heap-based buffer |
|
||||
| | | | | | over-read in the curl tool |
|
||||
| | | | | | warning formatting |
|
||||
+ +------------------+ + +---------------+----------------------------------+
|
||||
| | CVE-2018-16890 | | | 7.61.1-r2 | curl: NTLM type-2 heap |
|
||||
| | | | | | out-of-bounds buffer read |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3823 | | | | curl: SMTP end-of-response |
|
||||
| | | | | | out-of-bounds read |
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
| git | CVE-2018-17456 | HIGH | 2.15.2-r0 | 2.15.3-r0 | git: arbitrary code execution |
|
||||
| | | | | | via .gitmodules |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2018-19486 | | | | git: Improper handling of |
|
||||
| | | | | | PATH allows for commands to be |
|
||||
| | | | | | executed from... |
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
| libssh2 | CVE-2019-3855 | CRITICAL | 1.8.0-r2 | 1.8.1-r0 | libssh2: Integer overflow in |
|
||||
| | | | | | transport read resulting in |
|
||||
| | | | | | out of bounds write... |
|
||||
+ +------------------+----------+ + +----------------------------------+
|
||||
| | CVE-2019-3859 | MEDIUM | | | libssh2: Unchecked use of |
|
||||
| | | | | | _libssh2_packet_require and |
|
||||
| | | | | | _libssh2_packet_requirev |
|
||||
| | | | | | resulting in out-of-bounds |
|
||||
| | | | | | read |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3858 | | | | libssh2: Zero-byte allocation |
|
||||
| | | | | | with a specially crafted SFTP |
|
||||
| | | | | | packed leading to an... |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3863 | | | | libssh2: Integer overflow |
|
||||
| | | | | | in user authenticate |
|
||||
| | | | | | keyboard interactive allows |
|
||||
| | | | | | out-of-bounds writes |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3862 | | | | libssh2: Out-of-bounds memory |
|
||||
| | | | | | comparison with specially |
|
||||
| | | | | | crafted message channel |
|
||||
| | | | | | request |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3860 | | | | libssh2: Out-of-bounds reads |
|
||||
| | | | | | with specially crafted SFTP |
|
||||
| | | | | | packets |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3857 | | | | libssh2: Integer overflow in |
|
||||
| | | | | | SSH packet processing channel |
|
||||
| | | | | | resulting in out of... |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3861 | | | | libssh2: Out-of-bounds reads |
|
||||
| | | | | | with specially crafted SSH |
|
||||
| | | | | | packets |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-3856 | | | | libssh2: Integer overflow in |
|
||||
| | | | | | keyboard interactive handling |
|
||||
| | | | | | resulting in out of bounds... |
|
||||
+---------+------------------+ +-------------------+---------------+----------------------------------+
|
||||
| libxml2 | CVE-2018-14567 | | 2.9.7-r0 | 2.9.8-r1 | libxml2: Infinite loop when |
|
||||
| | | | | | --with-lzma is used allows for |
|
||||
| | | | | | denial of service... |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2018-14404 | | | | libxml2: NULL pointer |
|
||||
| | | | | | dereference in |
|
||||
| | | | | | xpath.c:xmlXPathCompOpEval() |
|
||||
| | | | | | can allow attackers to cause |
|
||||
| | | | | | a... |
|
||||
+ +------------------+----------+ + +----------------------------------+
|
||||
| | CVE-2018-9251 | LOW | | | libxml2: infinite loop in |
|
||||
| | | | | | xz_decomp function in xzlib.c |
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
| openssh | CVE-2019-6109 | MEDIUM | 7.5_p1-r9 | 7.5_p1-r10 | openssh: Missing character |
|
||||
| | | | | | encoding in progress display |
|
||||
| | | | | | allows for spoofing of scp... |
|
||||
+ +------------------+ + + +----------------------------------+
|
||||
| | CVE-2019-6111 | | | | openssh: Improper validation |
|
||||
| | | | | | of object names allows |
|
||||
| | | | | | malicious server to overwrite |
|
||||
| | | | | | files... |
|
||||
+ +------------------+----------+ + +----------------------------------+
|
||||
| | CVE-2018-20685 | LOW | | | openssh: scp client improper |
|
||||
| | | | | | directory name validation |
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
| sqlite | CVE-2018-20346 | MEDIUM | 3.21.0-r1 | 3.25.3-r0 | sqlite: Multiple flaws in |
|
||||
| | | | | | sqlite which can be triggered |
|
||||
| | | | | | via corrupted internal... |
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
| tar | CVE-2018-20482 | LOW | 1.29-r1 | 1.31-r0 | tar: Infinite read loop in |
|
||||
| | | | | | sparse_dump_region function in |
|
||||
| | | | | | sparse.c |
|
||||
+---------+------------------+----------+-------------------+---------------+----------------------------------+
|
||||
|
||||
ruby-app/Gemfile.lock
|
||||
=====================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+----------------------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+----------------------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| rails-html-sanitizer | CVE-2018-3741 | MEDIUM | 1.0.3 | >= 1.0.4 | rubygem-rails-html-sanitizer: |
|
||||
| | | | | | non-whitelisted attributes |
|
||||
| | | | | | are present in sanitized |
|
||||
| | | | | | output when input with |
|
||||
| | | | | | specially-crafted... |
|
||||
+----------------------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
|
||||
rust-app/Cargo.lock
|
||||
===================
|
||||
Total: 3 (UNKNOWN: 3, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+-------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+-------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| ammonia | RUSTSEC-2019-0001 | UNKNOWN | 1.9.0 | >= 2.1.0 | Uncontrolled recursion leads |
|
||||
| | | | | | to abort in HTML serialization |
|
||||
+---------+-------------------+ +-------------------+---------------+--------------------------------+
|
||||
| openssl | RUSTSEC-2016-0001 | | 0.8.3 | >= 0.9.0 | SSL/TLS MitM vulnerability due |
|
||||
| | | | | | to insecure defaults |
|
||||
+ +-------------------+ + +---------------+--------------------------------+
|
||||
| | RUSTSEC-2018-0010 | | | >= 0.10.9 | Use after free in CMS Signing |
|
||||
+---------+-------------------+----------+-------------------+---------------+--------------------------------+
|
||||
|
||||
php-app/composer.lock
|
||||
=====================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+-------------------+------------------+----------+-------------------+---------------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+-------------------+------------------+----------+-------------------+---------------------+--------------------------------+
|
||||
| guzzlehttp/guzzle | CVE-2016-5385 | MEDIUM | 6.2.0 | 6.2.1, 4.2.4, 5.3.1 | PHP: sets environmental |
|
||||
| | | | | | variable based on user |
|
||||
| | | | | | supplied Proxy request header |
|
||||
+-------------------+------------------+----------+-------------------+---------------------+--------------------------------+
|
||||
|
||||
node-app/package-lock.json
|
||||
==========================
|
||||
Total: 4 (UNKNOWN: 0, LOW: 0, MEDIUM: 3, HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| jquery | CVE-2019-5428 | MEDIUM | 3.3.9 | >=3.4.0 | Modification of |
|
||||
| | | | | | Assumed-Immutable Data (MAID) |
|
||||
+ +------------------+ + + +--------------------------------+
|
||||
| | CVE-2019-11358 | | | | js-jquery: prototype pollution |
|
||||
| | | | | | in object's prototype leading |
|
||||
| | | | | | to denial of service or... |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| lodash | CVE-2018-16487 | HIGH | 4.17.4 | >=4.17.11 | lodash: Prototype pollution in |
|
||||
| | | | | | utilities function |
|
||||
+ +------------------+----------+ +---------------+ +
|
||||
| | CVE-2018-3721 | MEDIUM | | >=4.17.5 | |
|
||||
| | | | | | |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
|
||||
python-app/Pipfile.lock
|
||||
=======================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+------------------------------------+
|
||||
| django | CVE-2019-6975 | MEDIUM | 2.0.9 | 2.0.11 | python-django: |
|
||||
| | | | | | memory exhaustion in |
|
||||
| | | | | | django.utils.numberformat.format() |
|
||||
+---------+------------------+----------+-------------------+---------------+------------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Scan an image file
|
||||
|
||||
```
|
||||
@@ -203,50 +461,45 @@ $ trivy --input ruby-2.3.0.tar
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T01:40:44.254+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T01:40:46.035+0900 INFO Detecting Debian vulnerabilities...
|
||||
2019-05-16T12:45:57.332+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T12:45:59.119+0900 INFO Detecting Debian vulnerabilities...
|
||||
|
||||
ruby-2.3.0.tar (debian 8.4)
|
||||
===========================
|
||||
Total: 8136 (UNKNOWN: 5, LOW: 326, MEDIUM: 6020, HIGH: 1680, CRITICAL: 105)
|
||||
Total: 7447 (UNKNOWN: 5, LOW: 326, MEDIUM: 5695, HIGH: 1316, CRITICAL: 105)
|
||||
|
||||
+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+-----------------------------+------------------+----------+---------------------------+----------------------------------+-------------------------------------------------+
|
||||
| bash | CVE-2016-7543 | HIGH | 4.3-11 | 4.3-11+deb8u1 | bash: Specially crafted |
|
||||
| | | | | | SHELLOPTS+PS4 variables allows |
|
||||
| | | | | | command substitution |
|
||||
+ +------------------+ + +----------------------------------+-------------------------------------------------+
|
||||
| | CVE-2019-9924 | | | 4.3-11+deb8u2 | bash: BASH_CMD is writable in |
|
||||
| | | | | | restricted bash shells |
|
||||
+-----------------------------+------------------+ +---------------------------+----------------------------------+-------------------------------------------------+
|
||||
| binutils | CVE-2017-13716 | | 2.25-5 | | binutils: Memory leak with the |
|
||||
| | | | | | C++ symbol demangler routine |
|
||||
| | | | | | in libiberty |
|
||||
+ +------------------+ + +----------------------------------+-------------------------------------------------+
|
||||
| | CVE-2017-14930 | | | | binutils: Memory leak in |
|
||||
| | | | | | decode_line_info |
|
||||
+ +------------------+ + +----------------------------------+-------------------------------------------------+
|
||||
| | CVE-2017-8421 | | | | binutils: Memory exhaustion in |
|
||||
| | | | | | objdump via a crafted PE file |
|
||||
+ +------------------+ + +----------------------------------+-------------------------------------------------+
|
||||
| | CVE-2017-7614 | | | | binutils: NULL |
|
||||
| | | | | | pointer dereference in |
|
||||
| | | | | | bfd_elf_final_link function |
|
||||
+ +------------------+ + +----------------------------------+-------------------------------------------------+
|
||||
| | CVE-2018-12699 | | | | binutils: heap-based buffer |
|
||||
| | | | | | overflow in finish_stab in |
|
||||
| | | | | | stabs.c |
|
||||
+ +------------------+ + +----------------------------------+-------------------------------------------------+
|
||||
| | CVE-2014-9939 | | | | binutils: buffer overflow in |
|
||||
| | | | | | ihex.c |
|
||||
+-----------------------------+------------------+ +---------------------------+----------------------------------+-------------------------------------------------+
|
||||
+------------------------------+---------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+------------------------------+---------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
|
||||
| apt | CVE-2019-3462 | CRITICAL | 1.0.9.8.3 | 1.0.9.8.5 | Incorrect sanitation of the |
|
||||
| | | | | | 302 redirect field in HTTP |
|
||||
| | | | | | transport method of... |
|
||||
+ +---------------------+----------+ +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2016-1252 | MEDIUM | | 1.0.9.8.4 | The apt package in Debian |
|
||||
| | | | | | jessie before 1.0.9.8.4, in |
|
||||
| | | | | | Debian unstable before... |
|
||||
+ +---------------------+----------+ +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2011-3374 | LOW | | | |
|
||||
+------------------------------+---------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
|
||||
| bash | CVE-2016-7543 | HIGH | 4.3-11 | 4.3-11+deb8u1 | bash: Specially crafted |
|
||||
| | | | | | SHELLOPTS+PS4 variables allows |
|
||||
| | | | | | command substitution |
|
||||
+ +---------------------+ + +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2019-9924 | | | 4.3-11+deb8u2 | bash: BASH_CMD is writable in |
|
||||
| | | | | | restricted bash shells |
|
||||
+ +---------------------+----------+ +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2016-0634 | MEDIUM | | 4.3-11+deb8u1 | bash: Arbitrary code execution |
|
||||
| | | | | | via malicious hostname |
|
||||
+ +---------------------+----------+ +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2016-9401 | LOW | | 4.3-11+deb8u2 | bash: popd controlled free |
|
||||
+ +---------------------+ + +----------------------------------+-----------------------------------------------------+
|
||||
| | TEMP-0841856-B18BAF | | | | |
|
||||
+------------------------------+---------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------
|
||||
...
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
### Save the results as JSON
|
||||
|
||||
```
|
||||
@@ -263,6 +516,115 @@ $ trivy -f json -o results.json golang:1.12-alpine
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
||||
```
|
||||
[
|
||||
{
|
||||
"Target": "php-app/composer.lock",
|
||||
"Vulnerabilities": null
|
||||
},
|
||||
{
|
||||
"Target": "node-app/package-lock.json",
|
||||
"Vulnerabilities": [
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-16487",
|
||||
"PkgName": "lodash",
|
||||
"InstalledVersion": "4.17.4",
|
||||
"FixedVersion": "\u003e=4.17.11",
|
||||
"Title": "lodash: Prototype pollution in utilities function",
|
||||
"Description": "A prototype pollution vulnerability was found in lodash \u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16487",
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Target": "trivy-ci-test (alpine 3.7.1)",
|
||||
"Vulnerabilities": [
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-16840",
|
||||
"PkgName": "curl",
|
||||
"InstalledVersion": "7.61.0-r0",
|
||||
"FixedVersion": "7.61.1-r1",
|
||||
"Title": "curl: Use-after-free when closing \"easy\" handle in Curl_close()",
|
||||
"Description": "A heap use-after-free flaw was found in curl versions from 7.59.0 through 7.61.1 in the code related to closing an easy handle. ",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-16840",
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2019-3822",
|
||||
"PkgName": "curl",
|
||||
"InstalledVersion": "7.61.0-r0",
|
||||
"FixedVersion": "7.61.1-r2",
|
||||
"Title": "curl: NTLMv2 type-3 header stack buffer overflow",
|
||||
"Description": "libcurl versions from 7.36.0 to before 7.64.0 are vulnerable to a stack-based buffer overflow. ",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://curl.haxx.se/docs/CVE-2019-3822.html",
|
||||
"https://lists.apache.org/thread.html/8338a0f605bdbb3a6098bb76f666a95fc2b2f53f37fa1ecc89f1146f@%3Cdevnull.infra.apache.org%3E"
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-16839",
|
||||
"PkgName": "curl",
|
||||
"InstalledVersion": "7.61.0-r0",
|
||||
"FixedVersion": "7.61.1-r1",
|
||||
"Title": "curl: Integer overflow leading to heap-based buffer overflow in Curl_sasl_create_plain_message()",
|
||||
"Description": "Curl versions 7.33.0 through 7.61.1 are vulnerable to a buffer overrun in the SASL authentication code that may lead to denial of service.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://github.com/curl/curl/commit/f3a24d7916b9173c69a3e0ee790102993833d6c5",
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-19486",
|
||||
"PkgName": "git",
|
||||
"InstalledVersion": "2.15.2-r0",
|
||||
"FixedVersion": "2.15.3-r0",
|
||||
"Title": "git: Improper handling of PATH allows for commands to be executed from the current directory",
|
||||
"Description": "Git before 2.19.2 on Linux and UNIX executes commands from the current working directory (as if '.' were at the end of $PATH) in certain cases involving the run_command() API and run-command.c, because there was a dangerous change from execvp to execv during 2017.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"https://usn.ubuntu.com/3829-1/",
|
||||
]
|
||||
},
|
||||
{
|
||||
"VulnerabilityID": "CVE-2018-17456",
|
||||
"PkgName": "git",
|
||||
"InstalledVersion": "2.15.2-r0",
|
||||
"FixedVersion": "2.15.3-r0",
|
||||
"Title": "git: arbitrary code execution via .gitmodules",
|
||||
"Description": "Git before 2.14.5, 2.15.x before 2.15.3, 2.16.x before 2.16.5, 2.17.x before 2.17.2, 2.18.x before 2.18.1, and 2.19.x before 2.19.1 allows remote code execution during processing of a recursive \"git clone\" of a superproject if a .gitmodules file has a URL field beginning with a '-' character.",
|
||||
"Severity": "HIGH",
|
||||
"References": [
|
||||
"http://www.securitytracker.com/id/1041811",
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Target": "python-app/Pipfile.lock",
|
||||
"Vulnerabilities": null
|
||||
},
|
||||
{
|
||||
"Target": "ruby-app/Gemfile.lock",
|
||||
"Vulnerabilities": null
|
||||
},
|
||||
{
|
||||
"Target": "rust-app/Cargo.lock",
|
||||
"Vulnerabilities": null
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Filter the vulnerabilities by severities
|
||||
|
||||
```
|
||||
@@ -328,35 +690,115 @@ Total: 1785 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1680, CRITICAL: 105)
|
||||
|
||||
### Skip an update of vulnerability DB
|
||||
|
||||
`Trivy` updates vulnerability database every time it is run. This is usually fast as it is a difference update. But if you want to skip even that, use the `--skip-update` option.
|
||||
`Trivy` always updates 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 alpine:3.9
|
||||
$ trivy --skip-update python:3.4-alpine3.9
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T12:48:08.703+0900 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
python:3.4-alpine3.9 (alpine 3.9.2)
|
||||
===================================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
|
||||
| | | | | | with long nonces |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Ignore unfixed vulnerabilities
|
||||
|
||||
By default, `Trivy` also detects unpatched/unfixed vulnerabilities. This means you can't fix these vulnerabilities even if you update all packages.
|
||||
If you would like to ignore them, use the `--ignore-unfixed` option.
|
||||
|
||||
```
|
||||
$ trivy --exit-code 1 httpd:2.4.39
|
||||
$ trivy --ignore-unfixed ruby:2.3.0
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
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)
|
||||
=======================
|
||||
Total: 4730 (UNKNOWN: 1, LOW: 145, MEDIUM: 3487, HIGH: 1014, CRITICAL: 83)
|
||||
|
||||
+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
|
||||
| apt | CVE-2019-3462 | CRITICAL | 1.0.9.8.3 | 1.0.9.8.5 | Incorrect sanitation of the |
|
||||
| | | | | | 302 redirect field in HTTP |
|
||||
| | | | | | transport method of... |
|
||||
+ +------------------+----------+ +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2016-1252 | MEDIUM | | 1.0.9.8.4 | The apt package in Debian |
|
||||
| | | | | | jessie before 1.0.9.8.4, in |
|
||||
| | | | | | Debian unstable before... |
|
||||
+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
|
||||
| bash | CVE-2019-9924 | HIGH | 4.3-11 | 4.3-11+deb8u2 | bash: BASH_CMD is writable in |
|
||||
| | | | | | restricted bash shells |
|
||||
+ +------------------+ + +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2016-7543 | | | 4.3-11+deb8u1 | bash: Specially crafted |
|
||||
| | | | | | SHELLOPTS+PS4 variables allows |
|
||||
| | | | | | command substitution |
|
||||
+ +------------------+----------+ + +-----------------------------------------------------+
|
||||
| | CVE-2016-0634 | MEDIUM | | | bash: Arbitrary code execution |
|
||||
| | | | | | via malicious hostname |
|
||||
+ +------------------+----------+ +----------------------------------+-----------------------------------------------------+
|
||||
| | CVE-2016-9401 | LOW | | 4.3-11+deb8u2 | bash: popd controlled free |
|
||||
+------------------------------+------------------+----------+----------------------------+----------------------------------+-----------------------------------------------------+
|
||||
...
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Specify exit code
|
||||
|
||||
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 httpd:2.4.39
|
||||
$ trivy --exit-code 1 python:3.4-alpine3.9
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T12:51:43.500+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T12:52:00.387+0900 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
python:3.4-alpine3.9 (alpine 3.9.2)
|
||||
===================================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
|
||||
| | | | | | with long nonces |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
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 httpd:2.4.39
|
||||
$ trivy --exit-code 1 --severity CRITICAL httpd:2.4.39
|
||||
$ trivy --exit-code 0 --severity MEDIUM,HIGH ruby:2.3.0
|
||||
$ trivy --exit-code 1 --severity CRITICAL ruby:2.3.0
|
||||
```
|
||||
|
||||
### Ignore the specified vulnerabilities
|
||||
@@ -369,19 +811,58 @@ $ cat .trivyignore
|
||||
CVE-2018-14618
|
||||
|
||||
# No impact in our settings
|
||||
CVE-2019-3855
|
||||
CVE-2019-1543
|
||||
|
||||
$ trivy composer:1.7.2
|
||||
$ trivy python:3.4-alpine3.9
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T12:53:10.076+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T12:53:28.134+0900 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
python:3.4-alpine3.9 (alpine 3.9.2)
|
||||
===================================
|
||||
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Clear image caches
|
||||
|
||||
The `--clear-cache` option removes image caches. This option is useful if the image which has the same tag is updated (such as when using `latest` tag).
|
||||
|
||||
```
|
||||
$ trivy --clear-cache redis:5.0.4
|
||||
$ trivy --clear-cache python:3.7
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T12:55:24.749+0900 INFO Removing image caches...
|
||||
2019-05-16T12:55:24.769+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T12:56:14.055+0900 INFO Detecting Debian vulnerabilities...
|
||||
|
||||
python:3.7 (debian 9.9)
|
||||
=======================
|
||||
Total: 3076 (UNKNOWN: 0, LOW: 127, MEDIUM: 2358, HIGH: 578, CRITICAL: 13)
|
||||
|
||||
+------------------------------+---------------------+----------+--------------------------+------------------+-------------------------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+------------------------------+---------------------+----------+--------------------------+------------------+-------------------------------------------------------+
|
||||
| apt | CVE-2011-3374 | LOW | 1.4.9 | | |
|
||||
+------------------------------+---------------------+ +--------------------------+------------------+-------------------------------------------------------+
|
||||
| bash | TEMP-0841856-B18BAF | | 4.4-5 | | |
|
||||
+------------------------------+---------------------+----------+--------------------------+------------------+-------------------------------------------------------+
|
||||
...
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Reset
|
||||
|
||||
The `--reset` option removes all caches and database. After this, it takes a long time as the vulnerability database needs to be rebuilt locally.
|
||||
@@ -390,11 +871,20 @@ The `--reset` option removes all caches and database. After this, it takes a lon
|
||||
$ trivy --reset
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T13:05:31.935+0900 INFO Resetting...
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
# Continuous Integration (CI)
|
||||
|
||||
Scan your image built in Travis CI/CircleCI. The test will fail if a vulnerability is found. When you don't want to fail the test, specify `--exit-code 0` .
|
||||
|
||||
**Note**: The first time take a while (faster by cache after the second time)
|
||||
**Note**: It will take a while for the first time (faster by cache after the second time)
|
||||
|
||||
## Travis CI
|
||||
|
||||
@@ -409,11 +899,12 @@ env:
|
||||
|
||||
before_install:
|
||||
- docker build -t trivy-ci-test:${COMMIT} .
|
||||
- wget https://github.com/knqyf263/trivy/releases/download/v0.0.4/trivy_0.0.4_Linux-64bit.tar.gz
|
||||
- tar zxvf trivy_0.0.4_Linux-64bit.tar.gz
|
||||
- export VERSION=$(curl --silent "https://api.github.com/repos/knqyf263/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
|
||||
- wget https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
|
||||
- tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
|
||||
script:
|
||||
- ./trivy --exit-code 0 --severity HIGH --quiet trivy-ci-test:${COMMIT}
|
||||
- ./trivy --exit-code 1 --severity CRITICAL --quiet trivy-ci-test:${COMMIT}
|
||||
- ./trivy --exit-code 0 --severity HIGH --quiet --auto-refresh trivy-ci-test:${COMMIT}
|
||||
- ./trivy --exit-code 1 --severity CRITICAL --quiet --auto-refresh trivy-ci-test:${COMMIT}
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/trivy
|
||||
@@ -425,6 +916,7 @@ Repository: https://github.com/knqyf263/trivy-ci-test
|
||||
## CircleCI
|
||||
|
||||
```
|
||||
$ cat .circleci/config.yml
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
@@ -440,12 +932,19 @@ jobs:
|
||||
- run:
|
||||
name: Install trivy
|
||||
command: |
|
||||
wget https://github.com/knqyf263/trivy/releases/download/v0.0.4/trivy_0.0.4_Linux-64bit.tar.gz
|
||||
tar zxvf trivy_0.0.4_Linux-64bit.tar.gz
|
||||
apk add --update curl
|
||||
VERSION=$(
|
||||
curl --silent "https://api.github.com/repos/knqyf263/trivy/releases/latest" | \
|
||||
grep '"tag_name":' | \
|
||||
sed -E 's/.*"v([^"]+)".*/\1/'
|
||||
)
|
||||
|
||||
wget https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
|
||||
tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
|
||||
mv trivy /usr/local/bin
|
||||
- run:
|
||||
name: Scan the local image with trivy
|
||||
command: trivy --exit-code 0 --quiet trivy-ci-test:${CIRCLE_SHA1}
|
||||
command: trivy --exit-code 0 --quiet --auto-refresh trivy-ci-test:${CIRCLE_SHA1}
|
||||
- save_cache:
|
||||
key: vulnerability-db
|
||||
paths:
|
||||
@@ -453,7 +952,7 @@ jobs:
|
||||
workflows:
|
||||
version: 2
|
||||
release:
|
||||
jobs:
|
||||
jobs:
|
||||
- build
|
||||
```
|
||||
|
||||
@@ -464,14 +963,16 @@ Repository: https://github.com/knqyf263/trivy-ci-test
|
||||
|
||||
## OS Packages
|
||||
|
||||
| OS | Supported Versions | Target Packages | Detection of unfixed vulnerabilities |
|
||||
| ---------------------------- | ---------------------------------------- | -------------------------------------- | --- |
|
||||
| Alpine Linux | 2.2 - 2.7, 3.0 - 3.10 | Installed by apk | NO |
|
||||
| Red Hat Universal Base Image | 7, 8 | Installed by yum/rpm | YES |
|
||||
| Red Hat Enterprise Linux | 6, 7, 8 | Installed by yum/rpm | YES |
|
||||
| CentOS | 6, 7 | Installed by yum/rpm | YES |
|
||||
| Debian GNU/Linux | wheezy, jessie, stretch, buster | Installed by apt/apt-get/dpkg | YES |
|
||||
| Ubuntu | 12.04, 14.04, 16.04, 18.04, 18.10, 19.04 | Installed by apt/apt-get/dpkg | YES |
|
||||
The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution.
|
||||
|
||||
| OS | Supported Versions | Target Packages | Detection of unfixed vulnerabilities |
|
||||
| ---------------------------- | ---------------------------------------- | ----------------------------- | :----------------------------------: |
|
||||
| Alpine Linux | 2.2 - 2.7, 3.0 - 3.10 | Installed by apk | NO |
|
||||
| Red Hat Universal Base Image | 7, 8 | Installed by yum/rpm | YES |
|
||||
| Red Hat Enterprise Linux | 6, 7, 8 | Installed by yum/rpm | YES |
|
||||
| CentOS | 6, 7 | Installed by yum/rpm | YES |
|
||||
| Debian GNU/Linux | wheezy, jessie, stretch, buster | Installed by apt/apt-get/dpkg | YES |
|
||||
| Ubuntu | 12.04, 14.04, 16.04, 18.04, 18.10, 19.04 | Installed by apt/apt-get/dpkg | YES |
|
||||
|
||||
## Application Dependencies
|
||||
|
||||
@@ -496,7 +997,7 @@ NAME:
|
||||
USAGE:
|
||||
main [options] image_name
|
||||
VERSION:
|
||||
0.0.12
|
||||
0.0.15
|
||||
OPTIONS:
|
||||
--format value, -f value format (table, json) (default: "table")
|
||||
--input value, -i value input file path instead of image name
|
||||
@@ -509,6 +1010,7 @@ OPTIONS:
|
||||
--quiet, -q suppress progress bar
|
||||
--ignore-unfixed display only fixed vulnerabilities
|
||||
--refresh refresh DB (usually used after version update of trivy)
|
||||
--auto-refresh refresh DB automatically when updating version of trivy
|
||||
--debug, -d debug mode
|
||||
--help, -h show help
|
||||
--version, -v print the version
|
||||
@@ -518,15 +1020,15 @@ OPTIONS:
|
||||
|
||||
## Overview
|
||||
|
||||
| Scanner | OS<br>Packages | Application<br>Dependencie | Easy to use | Accuracy | Compatible<br>with CI |
|
||||
|----------------|-------------|:-----------------------:|-------------|----------|--------------------|
|
||||
| Trivy | ◯ | ◯ | ◯ | ◎ | ◯ |
|
||||
| Clair | ◯ | × | △ | ◯ | △ |
|
||||
| Anchore Engine | ◯ | △ | △ | ◯ | △ |
|
||||
| Quay | ◯ | × | ◯ | ◯ | × |
|
||||
| MicroScanner | ◯ | × | ◯ | △ | ◯ |
|
||||
| Docker Hub | ◯ | × | ◯ | × | × |
|
||||
| GCR | ◯ | × | ◯ | ◯ | × |
|
||||
| Scanner | OS<br>Packages | Application<br>Dependencies | Easy to use | Accuracy | Suitable<br>for CI |
|
||||
| -------------- | :------------: | :-------------------------: | :---------: | :------: | :-------------------: |
|
||||
| Trivy | ◯ | ◯ | ◯ | ◎ | ◯ |
|
||||
| Clair | ◯ | × | △ | ◯ | △ |
|
||||
| Anchore Engine | ◯ | △ | △ | ◯ | △ |
|
||||
| Quay | ◯ | × | ◯ | ◯ | × |
|
||||
| MicroScanner | ◯ | × | ◯ | △ | ◯ |
|
||||
| Docker Hub | ◯ | × | ◯ | × | × |
|
||||
| GCR | ◯ | × | ◯ | ◯ | × |
|
||||
|
||||
## Accuracy
|
||||
|
||||
@@ -549,7 +1051,7 @@ The results of [composer:1.7.2](https://hub.docker.com/_/composer?tab=tags) usin
|
||||
|
||||
<img src="imgs/alpine.png" width="500">
|
||||
|
||||
`Trivy` has high accuracy and high precision, while GCR did not detect any vulnerability. Althogh Docker Hub has many True Positive, it also has many False Positive.
|
||||
`Trivy` has high accuracy and high precision, while GCR did not detect any vulnerability. Although Docker Hub has many True Positive, it also has many False Positive.
|
||||
|
||||
### RHEL/CentOS
|
||||
|
||||
@@ -561,7 +1063,7 @@ The following chart includes only fixable vulnerabilities.
|
||||
|
||||
Most scanners only detect patched/fixable vulnerabilities on RHEL/CentOS, but `Trivy` also detects unpatched/unfixable vulnerabilities.
|
||||
|
||||
The below is the graph including unfixable vulnerabilities.
|
||||
This graph includes unfixable vulnerabilities as well.
|
||||
|
||||
<img src="imgs/centos_include_unfixable.png" width="500">
|
||||
|
||||
@@ -575,8 +1077,8 @@ In the case of other OS, the result is similar to other container scanners.
|
||||
However, the purpose of this database is to make it possible to know what packages has backported fixes.
|
||||
As README says, it is not a complete database of all security issues in Alpine.
|
||||
|
||||
`Trivy` collects vulnerability information in Alpine Linux from [Alpine LInux Redmine](https://bugs.alpinelinux.org/projects/alpine/issues).
|
||||
Then, those vulnerabilities will be saved on [vuln-list](https://github.com/knqyf263/vuln-list/tree/master/alpine)
|
||||
`Trivy` collects vulnerability information in Alpine Linux from [Alpine Linux Redmine](https://bugs.alpinelinux.org/projects/alpine/issues).
|
||||
Then, those vulnerabilities will be saved on [vuln-list](https://github.com/knqyf263/vuln-list/tree/master/alpine).
|
||||
|
||||
`alpine-secdb` has 6959 vulnerabilities (as of 2019/05/12).
|
||||
`vuln-list` has 11101 vulnerabilities related with Alpine Linux (as of 2019/05/12).
|
||||
@@ -584,7 +1086,7 @@ There is a difference in detection accuracy because the number of vulnerabilitie
|
||||
|
||||
In addition, `Trivy` analyzes the middle layer as well and find out which version of the library was used for static linking.
|
||||
|
||||
`Clair` can not handle the following cases because it analyzes the image after applying the all layers.
|
||||
`Clair` can not handle the following cases because it analyzes the image after applying all layers.
|
||||
|
||||
```
|
||||
RUN apk add --no-cache sqlite-dev \
|
||||
@@ -594,6 +1096,8 @@ RUN apk add --no-cache sqlite-dev \
|
||||
&& apk del sqlite-dev
|
||||
```
|
||||
|
||||
And as many people know, it is difficult to select a `Clair` client because many clients are deprecated.
|
||||
|
||||
Finally, `Trivy` can also detect vulnerabilities in application dependent libraries such as Bundler, Composer, Pipenv, etc.
|
||||
|
||||
## vs Anchore Engine
|
||||
@@ -606,9 +1110,9 @@ Also, `Anchore Engine` needs some steps to start scanning.
|
||||
|
||||
## vs Quay, Docker Hub, GCR
|
||||
|
||||
As `Quay` seems to use `Clair` internally, it has the same accuracy with `Clair`. `Docker Hub` can scan only official images. `GCR` hardly detects vulnerability on Alpine Linux. Also, it is locked to a specific registry.
|
||||
As `Quay` seems to use `Clair` internally, it has the same accuracy than `Clair`. `Docker Hub` can scan only official images. `GCR` hardly detects vulnerabilities on Alpine Linux. Also, it is locked to a specific registry.
|
||||
|
||||
`Trivy` does not depend on the registry. In addition, it is easy to be integrated with CI/CD services.
|
||||
`Trivy` can be used regardless of the registry. In addition, it is easy to be integrated with CI/CD services.
|
||||
|
||||
# Q&A
|
||||
|
||||
@@ -666,6 +1170,11 @@ Try again with `--reset` option
|
||||
$ trivy --reset
|
||||
```
|
||||
|
||||
# Related Projects
|
||||
|
||||
- [Remic](https://github.com/knqyf263/remic)
|
||||
- Vulnerability Scanner for Detecting Publicly Disclosed Vulnerabilities in Application Dependencies
|
||||
|
||||
# Contribute
|
||||
|
||||
1. fork a repository: github.com/knqyf263/trivy to github.com/you/repo
|
||||
@@ -683,6 +1192,7 @@ $ trivy --reset
|
||||
|
||||
- Special thanks to [Tomoya Amachi](https://github.com/tomoyamachi)
|
||||
- Special thanks to [Masahiro Fujimura](https://github.com/masahiro331)
|
||||
- Special thanks to [Naoki Harima](https://github.com/XapiMa)
|
||||
|
||||
# License
|
||||
|
||||
|
||||
@@ -89,20 +89,26 @@ OPTIONS:
|
||||
Name: "refresh",
|
||||
Usage: "refresh DB (usually used after version update of trivy)",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "auto-refresh",
|
||||
Usage: "refresh DB automatically when updating version of trivy",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "debug, d",
|
||||
Usage: "debug mode",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "cache-dir",
|
||||
Usage: "cache directory",
|
||||
},
|
||||
}
|
||||
|
||||
app.Action = func(c *cli.Context) error {
|
||||
return pkg.Run(c)
|
||||
}
|
||||
app.Action = pkg.Run
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
if log.Logger != nil {
|
||||
log.Logger.Fatal(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
l.Fatal(err)
|
||||
}
|
||||
|
||||
4
go.mod
@@ -11,8 +11,8 @@ require (
|
||||
github.com/genuinetools/reg v0.16.0
|
||||
github.com/gliderlabs/ssh v0.1.3 // indirect
|
||||
github.com/golang/protobuf v1.3.1 // indirect
|
||||
github.com/knqyf263/fanal v0.0.0-20190516002914-a1530cdb9a80
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20170509080151-9865fe14d09b
|
||||
github.com/knqyf263/fanal v0.0.0-20190517090627-af48380166ef
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
|
||||
github.com/knqyf263/go-dep-parser v0.0.0-20190515172517-b8305876c9c2
|
||||
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936
|
||||
github.com/knqyf263/go-version v1.1.1
|
||||
|
||||
8
go.sum
@@ -114,10 +114,10 @@ github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp
|
||||
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/knqyf263/berkeleydb v0.0.0-20190501065933-fafe01fb9662/go.mod h1:bu1CcN4tUtoRcI/B/RFHhxMNKFHVq/c3SV+UTyduoXg=
|
||||
github.com/knqyf263/fanal v0.0.0-20190516002914-a1530cdb9a80 h1:6cXQOaOGU33P+22DKh6n7Pp+Tb5DLPwvqlJ7De34ZMg=
|
||||
github.com/knqyf263/fanal v0.0.0-20190516002914-a1530cdb9a80/go.mod h1:NQxdeR5taRqHUw9B2zkPCh/klHFaFb13j8QcQ6yxg60=
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20170509080151-9865fe14d09b h1:DiDMmSwuY27PJxA2Gs0+uI/bQ/ehKARaGXRdlp+wFis=
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20170509080151-9865fe14d09b/go.mod h1:o8sgWoz3JADecfc/cTYD92/Et1yMqMy0utV1z+VaZao=
|
||||
github.com/knqyf263/fanal v0.0.0-20190517090627-af48380166ef h1:mxKy5exy/vKIhV86Ar7E1AzNS/NCjfyrcRKcoblgZd8=
|
||||
github.com/knqyf263/fanal v0.0.0-20190517090627-af48380166ef/go.mod h1:bycEQTZsPG1IOBXWwTNxruhtNN0KYDgux0CMgu9UGoQ=
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d h1:X4cedH4Kn3JPupAwwWuo4AzYp16P0OyLO9d7OnMZc/c=
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d/go.mod h1:o8sgWoz3JADecfc/cTYD92/Et1yMqMy0utV1z+VaZao=
|
||||
github.com/knqyf263/go-dep-parser v0.0.0-20190515172517-b8305876c9c2 h1:bQGj8WH6X4czC2FlkgUKKFq2xPnJovzf61T4Yl9sVZs=
|
||||
github.com/knqyf263/go-dep-parser v0.0.0-20190515172517-b8305876c9c2/go.mod h1:gSiqSkOFPstUZu/qZ4wnNJS69PtQQnPl397vxKHJ5mQ=
|
||||
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936 h1:HDjRqotkViMNcGMGicb7cgxklx8OwnjtCBmyWEqrRvM=
|
||||
|
||||
BIN
imgs/alpine.png
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 44 KiB |
BIN
imgs/logo.png
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.8 KiB |
BIN
imgs/usage1.png
Normal file
|
After Width: | Height: | Size: 315 KiB |
BIN
imgs/usage2.png
Normal file
|
After Width: | Height: | Size: 215 KiB |
24
pkg/db/db.go
@@ -15,11 +15,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
db *bolt.DB
|
||||
dbDir = filepath.Join(utils.CacheDir(), "db")
|
||||
db *bolt.DB
|
||||
)
|
||||
|
||||
func Init() (err error) {
|
||||
dbDir := filepath.Join(utils.CacheDir(), "db")
|
||||
if err = os.MkdirAll(dbDir, 0700); err != nil {
|
||||
return xerrors.Errorf("failed to mkdir: %w", err)
|
||||
}
|
||||
@@ -33,10 +33,26 @@ func Init() (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Close() error {
|
||||
if err := db.Close(); err != nil {
|
||||
return xerrors.Errorf("failed to close DB: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Reset() error {
|
||||
if err := Close(); err != nil {
|
||||
return xerrors.Errorf("failed to reset DB: %w", err)
|
||||
}
|
||||
|
||||
dbDir := filepath.Join(utils.CacheDir(), "db")
|
||||
if err := os.RemoveAll(dbDir); err != nil {
|
||||
return xerrors.Errorf("failed to reset DB: %w", err)
|
||||
}
|
||||
|
||||
if err := Init(); err != nil {
|
||||
return xerrors.Errorf("failed to reset DB: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -89,9 +105,7 @@ func Put(root *bolt.Bucket, nestedBucket, key string, value interface{}) error {
|
||||
return nested.Put([]byte(key), v)
|
||||
}
|
||||
func BatchUpdate(fn func(tx *bolt.Tx) error) error {
|
||||
err := db.Batch(func(tx *bolt.Tx) error {
|
||||
return fn(tx)
|
||||
})
|
||||
err := db.Batch(fn)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error in batch update: %w", err)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func CloneOrPull(url, repoPath string) (map[string]struct{}, error) {
|
||||
}
|
||||
log.Logger.Debug("remove an existed directory")
|
||||
|
||||
suffix := " The first time will take a while..."
|
||||
suffix := " It will take a while for the first time..."
|
||||
s := utils.NewSpinner(suffix)
|
||||
s.Start()
|
||||
defer s.Stop()
|
||||
|
||||
@@ -6,9 +6,13 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var Logger *zap.SugaredLogger
|
||||
var (
|
||||
Logger *zap.SugaredLogger
|
||||
debugOption bool
|
||||
)
|
||||
|
||||
func InitLogger(debug bool) (err error) {
|
||||
debugOption = debug
|
||||
Logger, err = newLogger(debug)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error in new logger: %w", err)
|
||||
@@ -29,8 +33,8 @@ func newLogger(debug bool) (*zap.SugaredLogger, error) {
|
||||
Level: level,
|
||||
Encoding: "console",
|
||||
Development: debug,
|
||||
DisableStacktrace: !debug,
|
||||
DisableCaller: !debug,
|
||||
DisableStacktrace: true,
|
||||
DisableCaller: true,
|
||||
EncoderConfig: zapcore.EncoderConfig{
|
||||
TimeKey: "Time",
|
||||
LevelKey: "Level",
|
||||
@@ -53,3 +57,10 @@ func newLogger(debug bool) (*zap.SugaredLogger, error) {
|
||||
|
||||
return logger.Sugar(), nil
|
||||
}
|
||||
|
||||
func Fatal(err error) {
|
||||
if debugOption {
|
||||
Logger.Fatalf("%+v", err)
|
||||
}
|
||||
Logger.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
type Results []Result
|
||||
|
||||
type Result struct {
|
||||
FileName string `json:"file"`
|
||||
Vulnerabilities []vulnerability.DetectedVulnerability
|
||||
FileName string `json:"Target"`
|
||||
Vulnerabilities []vulnerability.DetectedVulnerability `json:"Vulnerabilities"`
|
||||
}
|
||||
|
||||
type Writer interface {
|
||||
@@ -84,11 +84,7 @@ type JsonWriter struct {
|
||||
}
|
||||
|
||||
func (jw JsonWriter) Write(results Results) error {
|
||||
out := map[string][]vulnerability.DetectedVulnerability{}
|
||||
for _, result := range results {
|
||||
out[result.FileName] = result.Vulnerabilities
|
||||
}
|
||||
output, err := json.MarshalIndent(out, "", " ")
|
||||
output, err := json.MarshalIndent(results, "", " ")
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to marshal json: %w", err)
|
||||
}
|
||||
|
||||
108
pkg/run.go
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/genuinetools/reg/registry"
|
||||
"github.com/knqyf263/fanal/cache"
|
||||
|
||||
"github.com/knqyf263/trivy/pkg/utils"
|
||||
@@ -25,13 +26,21 @@ import (
|
||||
func Run(c *cli.Context) (err error) {
|
||||
cliVersion := c.App.Version
|
||||
|
||||
utils.Quiet = c.Bool("quiet")
|
||||
debug := c.Bool("debug")
|
||||
if err = log.InitLogger(debug); err != nil {
|
||||
l.Fatal(err)
|
||||
}
|
||||
|
||||
cacheDir := c.String("cache-dir")
|
||||
if cacheDir != "" {
|
||||
utils.SetCacheDir(cacheDir)
|
||||
}
|
||||
|
||||
log.Logger.Debugf("cache dir: %s", utils.CacheDir())
|
||||
|
||||
if c.Bool("reset") {
|
||||
reset := c.Bool("reset")
|
||||
if reset {
|
||||
log.Logger.Info("Resetting...")
|
||||
if err = cache.Clear(); err != nil {
|
||||
return xerrors.New("failed to remove image layer cache")
|
||||
@@ -42,21 +51,65 @@ func Run(c *cli.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.Bool("clear-cache") {
|
||||
clearCache := c.Bool("clear-cache")
|
||||
if clearCache {
|
||||
log.Logger.Info("Removing image caches...")
|
||||
if err = cache.Clear(); err != nil {
|
||||
return xerrors.New("failed to remove image layer cache")
|
||||
}
|
||||
}
|
||||
|
||||
refresh := c.Bool("refresh")
|
||||
args := c.Args()
|
||||
var noTarget bool
|
||||
filePath := c.String("input")
|
||||
if filePath == "" && len(args) == 0 {
|
||||
log.Logger.Info(`trivy" requires at least 1 argument or --input option.`)
|
||||
cli.ShowAppHelpAndExit(c, 1)
|
||||
noTarget = true
|
||||
if !reset && !clearCache && !refresh {
|
||||
log.Logger.Info(`trivy" requires at least 1 argument or --input option.`)
|
||||
cli.ShowAppHelpAndExit(c, 1)
|
||||
}
|
||||
}
|
||||
|
||||
utils.Quiet = c.Bool("quiet")
|
||||
autoRefresh := c.Bool("auto-refresh")
|
||||
skipUpdate := c.Bool("skip-update")
|
||||
if (refresh || autoRefresh) && skipUpdate {
|
||||
return xerrors.New("The --skip-update option can not be specified with the --refresh or --auto-refresh option")
|
||||
}
|
||||
|
||||
if err = db.Init(); err != nil {
|
||||
return xerrors.Errorf("error in vulnerability DB initialize: %w", err)
|
||||
}
|
||||
|
||||
needRefresh := false
|
||||
dbVersion := db.GetVersion()
|
||||
if dbVersion != "" && dbVersion != cliVersion {
|
||||
if !refresh && !autoRefresh {
|
||||
return xerrors.New("Detected version update of trivy. Please try again with --refresh or --auto-refresh option")
|
||||
}
|
||||
needRefresh = true
|
||||
}
|
||||
|
||||
if refresh || needRefresh {
|
||||
log.Logger.Info("Refreshing DB...")
|
||||
if err = db.Reset(); err != nil {
|
||||
return xerrors.Errorf("error in refresh DB: %w", err)
|
||||
}
|
||||
}
|
||||
if !skipUpdate {
|
||||
if err = vulnsrc.Update(); err != nil {
|
||||
return xerrors.Errorf("error in vulnerability DB update: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = db.SetVersion(cliVersion); err != nil {
|
||||
return xerrors.Errorf("unexpected error: %w", err)
|
||||
}
|
||||
|
||||
// When specifying no image name and file name
|
||||
if noTarget {
|
||||
return nil
|
||||
}
|
||||
|
||||
o := c.String("output")
|
||||
output := os.Stdout
|
||||
@@ -76,40 +129,29 @@ func Run(c *cli.Context) (err error) {
|
||||
severities = append(severities, severity)
|
||||
}
|
||||
|
||||
if c.Bool("refresh") {
|
||||
log.Logger.Info("Resetting DB...")
|
||||
if err = db.Reset(); err != nil {
|
||||
return xerrors.Errorf("error in refresh DB: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = db.Init(); err != nil {
|
||||
return xerrors.Errorf("error in vulnerability DB initialize: %w", err)
|
||||
}
|
||||
|
||||
dbVersion := db.GetVersion()
|
||||
if dbVersion != "" && dbVersion != cliVersion {
|
||||
log.Logger.Fatal("Detected version update of trivy. Please try again with --refresh option")
|
||||
}
|
||||
|
||||
if !c.Bool("skip-update") {
|
||||
if err = vulnsrc.Update(); err != nil {
|
||||
return xerrors.Errorf("error in vulnerability DB update: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
ignoreUnfixed := c.Bool("ignore-unfixed")
|
||||
|
||||
var imageName string
|
||||
if filePath == "" {
|
||||
imageName = args[0]
|
||||
}
|
||||
|
||||
// Check whether 'latest' tag is used
|
||||
if imageName != "" {
|
||||
image, err := registry.ParseImage(imageName)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("invalid image: %w", err)
|
||||
}
|
||||
if image.Tag == "latest" && !clearCache {
|
||||
log.Logger.Warn("You should avoid using the :latest tag as it is cached. You need to specify '--clear-cache' option when :latest image is changed")
|
||||
}
|
||||
}
|
||||
|
||||
vulns, err := scanner.ScanImage(imageName, filePath)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error in image scan: %w", err)
|
||||
}
|
||||
|
||||
var results report.Results
|
||||
ignoreUnfixed := c.Bool("ignore-unfixed")
|
||||
for path, vuln := range vulns {
|
||||
results = append(results, report.Result{
|
||||
FileName: path,
|
||||
@@ -118,23 +160,19 @@ func Run(c *cli.Context) (err error) {
|
||||
}
|
||||
|
||||
var writer report.Writer
|
||||
switch c.String("format") {
|
||||
switch format := c.String("format"); format {
|
||||
case "table":
|
||||
writer = &report.TableWriter{Output: output}
|
||||
case "json":
|
||||
writer = &report.JsonWriter{Output: output}
|
||||
default:
|
||||
xerrors.New("unknown format")
|
||||
return xerrors.Errorf("unknown format: %v", format)
|
||||
}
|
||||
|
||||
if err = writer.Write(results); err != nil {
|
||||
return xerrors.Errorf("failed to write results: %w", err)
|
||||
}
|
||||
|
||||
if err = db.SetVersion(cliVersion); err != nil {
|
||||
return xerrors.Errorf("unexpected error: %w", err)
|
||||
}
|
||||
|
||||
exitCode := c.Int("exit-code")
|
||||
if exitCode != 0 {
|
||||
for _, result := range results {
|
||||
|
||||
@@ -41,7 +41,8 @@ func Scan(files extractor.FileMap) (string, string, []vulnerability.DetectedVuln
|
||||
case fos.RedHat, fos.CentOS:
|
||||
s = redhat.NewScanner()
|
||||
default:
|
||||
return "", "", nil, xerrors.New("unsupported os")
|
||||
log.Logger.Warnf("unsupported os : %s", os.Family)
|
||||
return "", "", nil, nil
|
||||
}
|
||||
pkgs, err := analyzer.GetPackages(files)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,10 +6,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/genuinetools/reg/registry"
|
||||
"github.com/knqyf263/fanal/analyzer"
|
||||
"github.com/knqyf263/fanal/extractor"
|
||||
"github.com/knqyf263/trivy/pkg/log"
|
||||
"github.com/knqyf263/trivy/pkg/scanner/library"
|
||||
"github.com/knqyf263/trivy/pkg/scanner/ospkg"
|
||||
"github.com/knqyf263/trivy/pkg/vulnsrc/vulnerability"
|
||||
@@ -25,14 +23,6 @@ func ScanImage(imageName, filePath string) (map[string][]vulnerability.DetectedV
|
||||
var target string
|
||||
var files extractor.FileMap
|
||||
if imageName != "" {
|
||||
image, err := registry.ParseImage(imageName)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("invalid image: %w", err)
|
||||
}
|
||||
if image.Tag == "latest" {
|
||||
log.Logger.Warn("You should avoid using the :latest tag as it is cached. You need to specify '--clear-cache' option when :latest image is changed")
|
||||
}
|
||||
|
||||
target = imageName
|
||||
files, err = analyzer.Analyze(ctx, imageName)
|
||||
if err != nil {
|
||||
@@ -58,8 +48,10 @@ func ScanImage(imageName, filePath string) (map[string][]vulnerability.DetectedV
|
||||
return nil, xerrors.Errorf("failed to scan image: %w", err)
|
||||
|
||||
}
|
||||
imageDetail := fmt.Sprintf("%s (%s %s)", target, osFamily, osVersion)
|
||||
results[imageDetail] = osVulns
|
||||
if osFamily != "" {
|
||||
imageDetail := fmt.Sprintf("%s (%s %s)", target, osFamily, osVersion)
|
||||
results[imageDetail] = osVulns
|
||||
}
|
||||
|
||||
libVulns, err := library.Scan(files)
|
||||
if err != nil {
|
||||
|
||||
@@ -12,15 +12,24 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
var cacheDir string
|
||||
|
||||
func CacheDir() string {
|
||||
cacheDir, err := os.UserCacheDir()
|
||||
if err != nil {
|
||||
cacheDir = os.TempDir()
|
||||
if cacheDir == "" {
|
||||
var err error
|
||||
cacheDir, err = os.UserCacheDir()
|
||||
if err != nil {
|
||||
cacheDir = os.TempDir()
|
||||
}
|
||||
}
|
||||
dir := filepath.Join(cacheDir, "trivy")
|
||||
return dir
|
||||
}
|
||||
|
||||
func SetCacheDir(cd string) {
|
||||
cacheDir = cd
|
||||
}
|
||||
|
||||
func FileWalk(root string, targetFiles map[string]struct{}, walkFn func(r io.Reader, path string) error) error {
|
||||
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() {
|
||||
|
||||
@@ -89,17 +89,16 @@ func getDetail(vulnID string) (Severity, string, string, []string) {
|
||||
|
||||
func getSeverity(details map[string]Vulnerability) Severity {
|
||||
for _, source := range sources {
|
||||
d, ok := details[source]
|
||||
if !ok {
|
||||
switch d, ok := details[source]; {
|
||||
case !ok:
|
||||
continue
|
||||
}
|
||||
if d.CvssScore > 0 {
|
||||
case d.CvssScore > 0:
|
||||
return scoreToSeverity(d.CvssScore)
|
||||
} else if d.CvssScoreV3 > 0 {
|
||||
case d.CvssScoreV3 > 0:
|
||||
return scoreToSeverity(d.CvssScoreV3)
|
||||
} else if d.Severity != 0 {
|
||||
case d.Severity != 0:
|
||||
return d.Severity
|
||||
} else if d.SeverityV3 != 0 {
|
||||
case d.SeverityV3 != 0:
|
||||
return d.SeverityV3
|
||||
}
|
||||
}
|
||||
@@ -151,14 +150,16 @@ func getReferences(details map[string]Vulnerability) []string {
|
||||
}
|
||||
|
||||
func scoreToSeverity(score float64) Severity {
|
||||
if score >= 9.0 {
|
||||
switch {
|
||||
case score >= 9.0:
|
||||
return SeverityCritical
|
||||
} else if score >= 7.0 {
|
||||
case score >= 7.0:
|
||||
return SeverityHigh
|
||||
} else if score >= 4.0 {
|
||||
case score >= 4.0:
|
||||
return SeverityMedium
|
||||
} else if score > 0.0 {
|
||||
case score > 0.0:
|
||||
return SeverityLow
|
||||
default:
|
||||
return SeverityUnknown
|
||||
}
|
||||
return SeverityUnknown
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func Update() (err error) {
|
||||
return xerrors.Errorf("error in Alpine OVAL update: %w", err)
|
||||
}
|
||||
|
||||
//Update RedHat
|
||||
// Update RedHat
|
||||
log.Logger.Info("Updating RedHat data...")
|
||||
if err = redhat.Update(dir, updatedFiles); err != nil {
|
||||
return xerrors.Errorf("error in RedHat update: %w", err)
|
||||
@@ -65,7 +65,7 @@ func Update() (err error) {
|
||||
return xerrors.Errorf("error in Debian OVAL update: %w", err)
|
||||
}
|
||||
|
||||
//Update Ubuntu
|
||||
// Update Ubuntu
|
||||
log.Logger.Info("Updating Ubuntu data...")
|
||||
if err = ubuntu.Update(dir, updatedFiles); err != nil {
|
||||
return xerrors.Errorf("error in Ubuntu update: %w", err)
|
||||
|
||||