# Low cost CVE scanning with Trivy

# Introduction

In a world of microservices, a production grade enterprise application comprises of hundreds of docker images. Organisations and their customers have a high focus on the security of applications and one of the key requirements is to keep the count of [Common Vulnerabilities and Exposures (CVEs)](https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures) to a minimum. Many organisations have strict policies that prevent a vulnerable image to be deployed on production environments. Furthermore, docker images are often made up of layers. So a CVE in one of the base layers will propagate to all images built using the particular base layer.

CVEs are a moving target. New CVEs are identified and detected by vulnerability scanners each day. This calls for a process that scans and fixes these vulnerabilities.

Docker images are immutable. It means that the only way to fix a Docker image is to build a new patch containing the fix. The last thing you want is to release a new build only to realize it contains a bunch of CRITICAL CVEs and is a NO-GO for production.

There are a number of CVE scanners available, however in this article we will use [Trivy](https://github.com/aquasecurity/trivy) from Aqua which is a free and open-source vulnerability scanner for images.

<div data-node-type="callout">
<div data-node-type="callout-emoji">🗒</div>
<div data-node-type="callout-text">v0.49 is the latest version at the time of writing this article.</div>
</div>

## Installation

Installing CVE is trivial. Follow the [steps](https://aquasecurity.github.io/trivy/v0.49/getting-started/installation/) for your platform of choice.

## Using the CLI

If installed using a package manager or as a binary, `trivy` is available through a command line tool.

Use the following command to verify the installation:

```plaintext
trivy version
```

To demonstrate the command used for scanning, let's use the `python:3.4-alpine` image:

```plaintext
trivy image python:3.4-alpine
```

The command results in an output that reports the *CVEs* in the image, along with the ID, severity, description and a fixed version (if available).

```plaintext
python:3.4-alpine (alpine 3.9.2)
```

```plaintext
Total: 37 (UNKNOWN: 0, LOW: 4, MEDIUM: 16, HIGH: 13, CRITICAL: 4)  
```

To capture the output in a file:

```plaintext
trivy image python:3.4-alpine > report.txt
```

Generally, `CRITICAL` and `HIGH` severity CVEs are considered as blockers for a release. So you may want the output to be filtered on `CRITICAL` and `HIGH` CVEs only.

For that, use the `-s` option

```plaintext
trivy image -s CRITICAL,HIGH python:3.4-alpine
```

## Run as a Docker Image

An alternative way, is to run `trivy` as a docker container.

<div data-node-type="callout">
<div data-node-type="callout-emoji">🗒</div>
<div data-node-type="callout-text">For scanning container images with trivy, mount <code>docker.sock</code> from the host into the <code>trivy</code> container.</div>
</div>

```plaintext
docker run -v /var/run/docker.sock:/var/run/docker.sock -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:0.49.1 image python:3.4-alpine
```

## Summary

Using `trivy` is an easy and cost-effective way of scanning images for CVEs. Integrating it in CI/CD pipelines is recommended.
