Trivy

Trivy (tri pronounced like trigger, vy pronounced like envy) is a simple and comprehensive vulnerability scanner for containers. A software vulnerability is a glitch, flaw, or weakness present in the software or in an Operating System. 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 an image name of the container.

Demo

Features

  • Detect comprehensive vulnerabilities
    • OS packages (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, Debian, Ubuntu, Amazon Linux and Distroless)
    • Application dependencies (Bundler, Composer, Pipenv, Poetry, npm, yarn and Cargo)
  • Simple
  • Easy installation
    • apt-get install, yum install and brew install is possible (See Installation)
    • No pre-requisites such as installation of DB, libraries, etc. (The exception is that you need rpm installed to scan images based on RHEL/CentOS. This is automatically included if you use our installers or the Trivy container image. See Vulnerability Detection for background information.)
  • High accuracy
    • Especially Alpine Linux and RHEL/CentOS
    • Other OSes are also high
  • DevSecOps
    • Suitable for CI such as Travis CI, CircleCI, Jenkins, etc.
    • See CI Example

Quick Start

Simply specify an image name (and a tag). The latest tag should be avoided as problems occur with the image cache. See Clear image caches.

Basic

$ trivy [YOUR_IMAGE_NAME]

For example:

$ trivy python:3.4-alpine

Docker

Replace [YOUR_CACHE_DIR] with the cache directory on your machine.

$ docker run --rm -v [YOUR_CACHE_DIR]:/root/.cache/ aquasec/trivy [YOUR_IMAGE_NAME]

Examples

Scan an image

Simply specify an image name (and a tag).

$ trivy knqyf263/vuln-image:1.2.3

Filter the vulnerabilities by severities

$ trivy --severity HIGH,CRITICAL ruby:2.3.0

Skip update of vulnerability DB

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

Update only specified distributions

By default, Trivy always updates its vulnerability database for all distributions. Use the --only-update option if you want to name specified distributions to update.

$ trivy --only-update alpine,debian python:3.4-alpine3.9
$ trivy --only-update alpine python:3.4-alpine3.9

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.

$ trivy --download-db-only
$ trivy --download-db-only --only-update alpine

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 --ignore-unfixed ruby:2.3.0

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 python:3.4-alpine3.9

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

Ignore the specified vulnerabilities

Use .trivyignore.

$ cat .trivyignore
# Accept the risk
CVE-2018-14618

# No impact in our settings
CVE-2019-1543

$ trivy python:3.4-alpine3.9

Specify cache directory

$ trivy --cache-dir /tmp/trivy/ python:3.4-alpine3.9

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 python:3.7

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.

$ trivy --reset

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: It will take a while for the first time (faster by cache after the second time).

Travis CI

$ cat .travis.yml
services:
  - docker

env:
  global:
    - COMMIT=${TRAVIS_COMMIT::8}

before_install:
  - docker build -t trivy-ci-test:${COMMIT} .
  - export VERSION=$(curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
  - wget https://github.com/aquasecurity/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 --no-progress --auto-refresh trivy-ci-test:${COMMIT}
  - ./trivy --exit-code 1 --severity CRITICAL --no-progress --auto-refresh trivy-ci-test:${COMMIT}
cache:
  directories:
    - $HOME/.cache/trivy

Example: https://travis-ci.org/aquasecurity/trivy-ci-test
Repository: https://github.com/aquasecurity/trivy-ci-test

CircleCI

$ cat .circleci/config.yml
jobs:
  build:
    docker:
      - image: docker:18.09-git
    steps:
      - checkout
      - setup_remote_docker
      - restore_cache:
          key: vulnerability-db
      - run:
          name: Build image
          command: docker build -t trivy-ci-test:${CIRCLE_SHA1} .
      - run:
          name: Install trivy
          command: |
            apk add --update curl
            VERSION=$(
                curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | \
                grep '"tag_name":' | \
                sed -E 's/.*"v([^"]+)".*/\1/'
            )

            wget https://github.com/aquasecurity/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 --no-progress --auto-refresh trivy-ci-test:${CIRCLE_SHA1}
      - save_cache:
          key: vulnerability-db
          paths:
            - $HOME/.cache/trivy
workflows:
  version: 2
  release:
    jobs:
      - build

Example: https://circleci.com/gh/aquasecurity/trivy-ci-test
Repository: https://github.com/aquasecurity/trivy-ci-test

GitLab

$ cat .gitlab-ci.yml
stages:
  - test

trivy:
  stage: test
  image: docker:stable-git
  before_script:
    - docker build -t trivy-ci-test:${CI_COMMIT_REF_NAME} .
    - export VERSION=$(curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    - wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
    - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
  variables:
    DOCKER_DRIVER: overlay2
  allow_failure: true
  services:
    - docker:stable-dind
  script:
    - ./trivy --exit-code 0 --severity HIGH --no-progress --auto-refresh trivy-ci-test:${CI_COMMIT_REF_NAME}
    - ./trivy --exit-code 1 --severity CRITICAL --no-progress --auto-refresh trivy-ci-test:${CI_COMMIT_REF_NAME}
  cache:
    directories:
      - $HOME/.cache/trivy

Authorization for Private Docker Registry

Trivy can download images from a private registry, without installing Docker or any other 3rd party tools. That’s because it’s easy to run in a CI process.

All you have to do is install Trivy and set ENV vars. But, I can’t recommend using ENV vars in your local machine to you.

Docker Hub

Docker Hub needs TRIVY_AUTH_URL, TRIVY_USERNAME and TRIVY_PASSWORD. You don’t need to set ENV vars when download from public repository.

export TRIVY_AUTH_URL=https://registry.hub.docker.com
export TRIVY_USERNAME={DOCKERHUB_USERNAME}
export TRIVY_PASSWORD={DOCKERHUB_PASSWORD}

Amazon ECR (Elastic Container Registry)

Trivy uses AWS SDK. You don’t need to install aws CLI tool. You can use AWS CLI’s ENV Vars.

GCR (Google Container Registry)

Trivy uses Google Cloud SDK. You don’t need to install gcloud command.

If you want to use target project’s repository, you can settle via GOOGLE_APPLICATION_CREDENTIAL.

# must set TRIVY_USERNAME empty char
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json

Self Hosted Registry (BasicAuth)

BasicAuth server needs TRIVY_USERNAME and TRIVY_PASSWORD.

export TRIVY_USERNAME={USERNAME}
export TRIVY_PASSWORD={PASSWORD}

# if you want to use 80 port, use NonSSL
export TRIVY_NON_SSL=true

Vulnerability Detection

OS Packages

The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution.

OSSupported VersionsTarget PackagesDetection of unfixed vulnerabilities
Alpine Linux2.2 - 2.7, 3.0 - 3.10Installed by apkNO
Red Hat Universal Base Image7, 8Installed by yum/rpmYES
Red Hat Enterprise Linux6, 7, 8Installed by yum/rpmYES
CentOS6, 7Installed by yum/rpmYES
Amazon Linux1, 2Installed by apt/apt-get/dpkgNO
Debian GNU/Linuxwheezy, jessie, stretch, busterInstalled by apt/apt-get/dpkgYES
Ubuntu12.04, 14.04, 16.04, 18.04, 18.10, 19.04Installed by apt/apt-get/dpkgYES
DistrolessAnyInstalled by apt/apt-get/dpkgYES

RHEL, CentOS and Amazon Linux package information is stored in a binary format, and Trivy uses the rpm executable to parse this information when scanning an image based on RHEL or CentOS. The Trivy container image includes rpm, and the installers include it as a dependency. If you installed the trivy binary using wget or curl, or if you build it from source, you will also need to ensure that rpm is available.

Distroless: https://github.com/GoogleContainerTools/distroless

Application Dependencies

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

  • Gemfile.lock
  • Pipfile.lock
  • poetry.lock
  • composer.lock
  • package-lock.json
  • yarn.lock
  • Cargo.lock

The path of these files does not matter.

Example: https://github.com/aquasecurity/trivy-ci-test/blob/master/Dockerfile

Image Tar format

Trivy scans a tar image with the following format.

  • Docker Image Specification (https://github.com/moby/moby/tree/master/image/spec)
    • Moby Project (https://github.com/moby/moby/)
    • Buildah, Podman (https://github.com/containers/buildah)
    • img (https://github.com/genuinetools/img)
  • Kaniko
    • Kaniko (https://github.com/GoogleContainerTools/kaniko)

Data source

  • PHP
    • https://github.com/FriendsOfPHP/security-advisories
  • Python
    • https://github.com/pyupio/safety-db
  • Ruby
    • https://github.com/rubysec/ruby-advisory-db
  • Node.js
    • https://github.com/nodejs/security-wg
  • Rust
    • https://github.com/RustSec/advisory-db

Usage

NAME:
  trivy - A simple and comprehensive vulnerability scanner for containers
USAGE:
  trivy [options] image_name
VERSION:
  0.1.6
OPTIONS:
  --format value, -f value    format (table, json) (default: "table")
  --input value, -i value     input file path instead of image name
  --severity value, -s value  severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
  --output value, -o value    output file name
  --exit-code value           Exit code when vulnerabilities were found (default: 0)
  --skip-update               skip db update
  --only-update value         update db only specified distribution (comma separated)
  --reset                     remove all caches and database
  --clear-cache, -c           clear image caches
  --quiet, -q                 suppress progress bar and log output
  --no-progress               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
  --vuln-type value           comma-separated list of vulnerability types (os,library) (default: "os,library")
  --cache-dir value           cache directory (default: "/path/to/cache")
  --help, -h                  show help
  --version, -v               print the version

Comparison with other scanners

Overview

ScannerOS
Packages
Application
Dependencies
Easy to useAccuracySuitable
for CI
Trivy
Clair×
Anchore Engine
Quay××
MicroScanner×
Docker Hub×××
GCR××

vs Clair

Clair uses alpine-secdb. 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 aports repository. Then, those vulnerabilities will be saved on vuln-list.

alpine-secdb has 6959 vulnerabilities (as of 2019/05/12). vuln-list has 11101 vulnerabilities related to Alpine Linux (as of 2019/05/12). There is a difference in detection accuracy because the number of vulnerabilities is nearly doubled.

In addition, Trivy analyzes the middle layers as well to 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 all layers.

RUN apk add --no-cache sqlite-dev \
 && wget https://xxx/yyy.tar.gz \
 && tar zxvf yyy.tar.gz && cd yyy \
 && make && make install \
 && 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

Similar to Clair, there is a difference in detection accuracy on Alpine Linux. Then, as noted above, Anchore Engine does not detect unfixable vulnerabilities on RHEL/CentOS, whereas Trivy does.

Also, Anchore Engine needs some steps to start scanning. Trivy is much easier to use.

vs Quay, Docker Hub, GCR

As Quay seems to use Clair internally, it has the same accuracy as Clair. Docker Hub can scan only official images. GCR hardly detects vulnerabilities on Alpine Linux. Also, it is locked to a specific registry.

Trivy can be used regardless of the registry, and it is easily integrated with CI/CD services.

Migration

On 19 August 2019, Trivy’s repositories moved from knqyf263/trivy to aquasecurity/trivy. If you previously installed Trivy you should update any scripts or package manager records as described in this section.

Overview

If you have a script that installs Trivy (for example into your CI pipelines) you should update it to obtain it from the new location by replacing knqyf263/trivy with aquasecurity/trivy.

For example:

# Before
$ wget https://github.com/knqyf263/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz

# After
$ wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz

Debian/Ubuntu

$ apt-get remove --purge trivy
$ sed -i s/knqyf263/aquasecurity/g /etc/apt/sources.list.d/trivy.list
$ apt-get update
$ apt-get install trivy






About

Welcome to 0x1.gitlab.io my personal blog to share my knowledge
Cyber Security, Ethical Hacking, Web & Network Auditing, Reverse Engineering and Cryptography
Website semi-configured to use with No-Script. No ADS and No use analytics tracking.


Contact

Forum : @0x1


© 0x1 | Cyber Security Consulting - Copyright All Rights Reserved