Aller au contenu

Trivy scanne les vulns de conteneurs

logo

C’est un fait les conteneurs sont de plus en plus utilisés, car ils facilitent la création et déploiements des applications. Mais attention, la sécurité des conteneurs est très importante, parce que vous pouvez rapidement créer de graves failles dans votre SI. En effet, par exemple récemment il a été détecté des conteneurs de la registry docker intégrant un ver de cryptojacking. Même si ces conteneurs ont été retirés, il est plus sage de soit construire ces images, soit de les scanner pour en connaître les vulnérabilités.

Il existe toute série de scanner dont voici la liste :

  • Anchor engine
  • Clair
  • Quay
  • MicroScanner
  • GCR
  • Trivy

C’est à ce dernier que je me suis intéressé.

Installation de trivy

Trivy est disponible sous forme d’image :

Terminal window
docker pull aquasec/trivy:latest

Utilisation de trivy

Nous allons nous intéresser à la version package et nous verrons plus tard comment l’intégrer dans votre CI.

Le plus simple est de lancer la commande sur cette image. Avant, il faut créer un dossier de cache :

Terminal window
mkdir -p ~/.cache/trivy
docker run --rm -v ~/.cache:/root/.cache/ -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image alpine:3.10
2021-10-05T16:56:16.686Z INFO Detected OS: alpine
2021-10-05T16:56:16.686Z INFO Detecting Alpine vulnerabilities...
2021-10-05T16:56:16.688Z INFO Number of language-specific files: 0
2021-10-05T16:56:16.688Z WARN This OS version is no longer supported by the distribution: alpine 3.10.9
2021-10-05T16:56:16.688Z WARN The vulnerability detection may be insufficient because security updates are not provided
alpine:3.10 (alpine 3.10.9)
===========================
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
+-----------+------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+-----------+------------------+----------+-------------------+---------------+---------------------------------------+
| apk-tools | CVE-2021-36159 | CRITICAL | 2.10.6-r0 | 2.10.7-r0 | libfetch before 2021-07-26, as |
| | | | | | used in apk-tools, xbps, and |
| | | | | | other products, mishandles... |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-36159 |
+-----------+------------------+----------+-------------------+---------------+---------------------------------------+

Lors du premier run, trivy va installer en local une base de données de vulnérabilités dans le répertoire : ~/.cache/trivy

Ensuite, il passe au scan à proprement parlé du contenu de l’image. En fait, il liste tous les packages installés et recherche dans sa bdd les vulnérabilités de ceux-ci.

Prenons exemple de l’image alpine:3.9.2

+---------+------------------+----------+-------------------+---------------+--------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+---------+------------------+----------+-------------------+---------------+--------------------------------+
| musl | CVE-2019-14697 | HIGH | 1.1.20-r3 | 1.1.20-r5 | musl libc through 1.1.23 |
| | | | | | has an x87 floating-point |
| | | | | | stack adjustment imbalance, |
| | | | | | related... |
+---------+------------------+----------+-------------------+---------------+--------------------------------+
| openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
| | | | | | with long nonces |
+ +------------------+ + +---------------+--------------------------------+
| | CVE-2019-1549 | | | 1.1.1d-r0 | openssl: information |
| | | | | | disclosure in fork() |
+ +------------------+ + + +--------------------------------+
| | CVE-2019-1563 | | | | openssl: information |
| | | | | | disclosure in PKCS7_dataDecode |
| | | | | | and CMS_decrypt_set1_pkey |
+ +------------------+----------+ + +--------------------------------+
| | CVE-2019-1547 | LOW | | | openssl: side-channel weak |
| | | | | | encryption vulnerability |
+---------+------------------+----------+-------------------+---------------+--------------------------------+

On voit qu’il y en a plusieurs dont une critique.

Faites le test par exemple sur l’image mysql et vous comprendrez pourquoi il est plus sage de construire ses propres images en n’intégrant que les packages nécessaires.

Il est possible de demander à trivy de ressortir en erreur sur la présence de vulnérabilités de type CRITICAL ou HIGH.

Terminal window
docker run --rm -v ~/.cache:/root/.cache/ -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy --skip-update --quiet --exit-code 1 --severity HIGH,CRITICAL image alpine:3.9.2

Avec comme résultat :

2019-10-25T14:04:26.566+0200 INFO Detecting Alpine vulnerabilities...
alpine:3.9.2 (alpine 3.9.2)
===========================
Total: 10 (HIGH: 8, CRITICAL: 2)
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
| libcrypto1.1 | CVE-2019-1543 | HIGH | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
| | | | | | with long nonces |
| | | | | | -->avd.aquasec.com/nvd/cve-2019-1543 |
+ +------------------+ + +---------------+---------------------------------------+
| | CVE-2020-1967 | | | 1.1.1g-r0 | openssl: Segmentation |
| | | | | | fault in SSL_check_chain |
| | | | | | causes denial of service |
| | | | | | -->avd.aquasec.com/nvd/cve-2020-1967 |
+ +------------------+ + +---------------+---------------------------------------+
| | CVE-2021-23840 | | | 1.1.1j-r0 | openssl: integer |
| | | | | | overflow in CipherUpdate |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 |
+ +------------------+ + +---------------+---------------------------------------+
| | CVE-2021-3450 | | | 1.1.1k-r0 | openssl: CA certificate check |
| | | | | | bypass with X509_V_FLAG_X509_STRICT |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-3450 |
+--------------+------------------+ + +---------------+---------------------------------------+
| libssl1.1 | CVE-2019-1543 | | | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
| | | | | | with long nonces |
| | | | | | -->avd.aquasec.com/nvd/cve-2019-1543 |
+ +------------------+ + +---------------+---------------------------------------+
| | CVE-2020-1967 | | | 1.1.1g-r0 | openssl: Segmentation |
| | | | | | fault in SSL_check_chain |
| | | | | | causes denial of service |
| | | | | | -->avd.aquasec.com/nvd/cve-2020-1967 |
+ +------------------+ + +---------------+---------------------------------------+
| | CVE-2021-23840 | | | 1.1.1j-r0 | openssl: integer |
| | | | | | overflow in CipherUpdate |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-23840 |
+ +------------------+ + +---------------+---------------------------------------+
| | CVE-2021-3450 | | | 1.1.1k-r0 | openssl: CA certificate check |
| | | | | | bypass with X509_V_FLAG_X509_STRICT |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-3450 |
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+
| musl | CVE-2019-14697 | CRITICAL | 1.1.20-r3 | 1.1.20-r5 | musl libc through 1.1.23 has |
| | | | | | an x87 floating-point stack |
| | | | | | adjustment imbalance, related... |
| | | | | | -->avd.aquasec.com/nvd/cve-2019-14697 |
+--------------+ + + + + +
| musl-utils | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
+--------------+------------------+----------+-------------------+---------------+---------------------------------------+

Pratique pour l’intégrer dans votre CI.

Intégration dans Gitlab-CI

Comme vu précédemment, il existe une version sous forme de container qui peut être intégré à votre CI. J’ai créé un runner dédié à trivy. En effet, j’ai décidé de mettre le cache de trivy dans un répertoire de ma VM et de le monter sur le volume /cache.

Dans mon gitlab-ci.yaml j’ai intégré le step suivant en indiquant que le cache se trouve dans /cache/trivy.

trivy:
image:
name: aquasec/trivy
entrypoint: [""]
tags:
- trivy
script:
- trivy --skip-update --quiet --cache-dir /cache/trivy --exit-code 1 --severity HIGH,CRITICAL --format table --output report.md --vuln-type os image $IMAGE

Pour éviter les updates pendant le run du ci, j’ai créé un job cron qui vient mettre à jour ce cache toutes les 2h.