Integrating Trivy with gitlab

What is Trivy?

Trivy is a simple vulnerability scanner developed by aquasecurity for scanning containers and other artifacts .It is mostly used for static analysis. It is suitable to integrate with CI phase of pipeline . Aquasecurity is widely know for building security tools towards container and pipeline security . Trivy is available in github here .

What does Trivy do?

As suggested above, it is a vulnerability scanner which is mostly helpful for detecting container level vulnerabilities and dependencies.At it’s core, it is mostly a CVE scanner useful for finding missing patches and already existing and publicly disclosed vulnerabilities. It can be used as a standalone binary to scan containers or it can be integrated with CI (the more common use).

Tools similar to Trivy?

1.Anchore

2.Clair

How to install it?

Clear instructions are given in the github link on how to install it. For this demonstration, we shall be using a kali linux 2020.3 instance. For debian instances, it’s extremely easy to install. Simply use this one liner to install trivy .

curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/master/contrib/install.sh | sh -s — -b /usr/local/bin

Scanning an image locally using Trivy.

It is extremely simple to scan a standalone image using Trivy. The syntax to scan an image is as below:

trivy image <image name>

Keep in mind that scanning image is just one feature of Trivy. You can scan repos,containers , project and more as well. For simplicity purposes in this blog to demonstrate the tool, scanning an image is more than enough .

We have chosen an image ‘knqyf263/vuln-image:1.2.3’ , a purposely built vulnerable image for demonstration purposes. Below is a screenshot of results of scanning.

Naturally this screenshot doesn’t completely show all the vulnerabilities . But this is essentially how we can scan locally built artifacts. We can even save the output to a file and of format of our choice. For example , if we wanted to store it in json format in a file named trivy.json, our command would be something like this:

trivy image -f json -o trivy.json <image>

The -f parameter is responsible for display format, the -o parameter is to name the file to save . More such options can be easily explored in the official github page.

Integration with CI/CD pipeline.

We shall use a gitlab pipeline to demonstrate working of trivy. First ,please create a repository in gitlab .

After creating the repository , we shall create a .gitlab-ci.yml file with the following code:

stages:

- test

trivy:

stage: test

image: docker:stable-git

before_script:

- docker build -t trivy-ci-test .

- wget https://github.com/aquasecurity/trivy/releases/download/v0.1.6/trivy_0.1.6_Linux-64bit.tar.gz

- tar zxvf trivy_0.1.6_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

- ./trivy — exit-code 1 — severity CRITICAL — no-progress — auto-refresh trivy-ci-test

The code is very simple to understand. Here we’re trying to build the image and then scan it for vulnerabilities. If and only if any critical vulnerabilities are found, the buld shall fail. Note that for demonstration purposes , we haven’t specified any output file as we shall navigate to the pipeline and see the output of vulnerabilities.

The code for the Dockerfile is as shown below:

FROM composer:1.7.2

RUN git clone https://github.com/aquasecurity/trivy-ci-test.git && cd trivy-ci-test && rm Cargo.lock && rm Pipfile.lock

CMD apk add — no-cache mysql-client

ENTRYPOINT [“mysql”]

Here again, we are simply trying to recreate a publicly available project made by the makers of Trivy itself for testing purposes.

After committing those files , wait for some time and go to CI/CD — ->Jobs and see the gitlab-terminal. We observe that the build has failed. Let us investigate as to why it has failed:

Scrolling through the commands, we can see that the trivy scanning commands have run and it’s displaying the vulnerabilities as well .For high vulnerabilities:

For critical vulnerabilities:

But there might be still a little bit of confusion as to why exactly the build failed? For that let us analyse these two trivy commands in the yml file we wrote:

- ./trivy — exit-code 0 — severity HIGH — no-progress — auto-refresh trivy-ci-test

- ./trivy — exit-code 1 — severity CRITICAL — no-progress — auto-refresh trivy-ci-test

It’s easy to guess what the commands must be doing. The first command scans for high severity vulnerabilities and if found, it shall exit the test with exit -code 0. The second command scans for critical severity vulnerabilities and if found, it shall exit the test with exit code 1.

As per Trivy documentation, if the test ends with any exit code other then 0, the build shall fail. Since trivy found critical vulnerabilities in the image, hence the build has failed :(

Also gitlab terminal:

Testing for a passed build :

We modified the .gitlab-ci.yml file and removed the second trivy command . So essentially the only trivy command we have is :

./trivy — exit-code 0 — severity HIGH — no-progress — auto-refresh trivy-ci-test

As a commit was made, we wait for a few moments. Once the job is complete, we can see our build has passed :)

Jobs:

And the gitlab-terminal:

Here we saw the distinction between a passed build and a failed build.

Conclusion:

Trivy is an astoundingly simple and amazingly documented open source vulnerability scanner tool. Here we tried to implement a very basic utility and example of the tool using gitlab pipeline. For entire workings and use cases of the tool, its best to go through the github documentation.

Cats, pizza and cyber security are all I live for! Follow me for a wide variety of topics in the field of cyber security. OSCP ,CRTE , CRTP ,CKAD holder.