CycloneDX et dépendency track : luter contre les CVE importées de l'extérieur

L’OWASP publie une liste de dix typologies de failles de sécurité, appelé le OWASP TOP 10. Celle qui nous intéresse aujourd’hui est la numéro 6 du classement 2021 "Les composants vulnérables et non mis à jour.

La question qui nous intéresse sera donc "Comment faire pour s’assurer que nos projets n’incluent pas de dépendances vulnérables".

En particulier, nous allons nous concentrer sur les projets Java.

Dependency check, les bases de CVE

Dependency Check

L’OWASP fournit un ensemble assez conséquents d’outils pour monitorer les projets, notamment vos dépendances.

Le plus ancien est dependency-check et notamment le plugin maven qui l’accompagne1.

L’intégration à maven est aussi simple que verbeuse à un détail près que nous verrons plus tard.

Le dependency-check tournera sur le lifecycle site et fournira un rapport html que vous pourrez ensuite exploiter.

Pour avoir dans le cadre professionnel implémenté un script qui interprète le rapport HTML pour extraire les données et les mettre dans une base de données pour ensuite faire un rapport synthétique, je peux vous dire que le HTML produit est au mieux pas optimisé. Ceci dit il est parsable sans erreur par n’importe quelle lib, comme BeautifulSoup4 si vous aimez python.

    <reporting>
        <plugins>
            <plugin>
                <groupId>org.owasp</groupId>
                <artifactId>dependency-check-maven</artifactId>
                <version>7.4.1</version>
                <reportSets>
                    <reportSet>
                        <reports>
                            <report>check</report>
                        </reports>
                    </reportSet>
                </reportSets>
            </plugin>
        </plugins>  
    </reporting>
Le code minimal à mettre dans votre pom pour faire fonctionner dépendency check

Vous pouvez désormais lancer mvn site ou encore mvn org.owasp:dependency-check-maven:check et il produira un fichier html tel que celui donné en exemple sur la documentation officielle.

C’est moche mais ça fait le taf, vous avez toutes les informations nécessaires.

Par contre je vous l’annonce tout de suite, ça peut rapidement prendre du temps : les bases de données doivent être chargées et si votre CI/CD gère mal les caches2, ce simple téléchargement peut rapidement vous prendre 5/10 minutes où le plugin met un coeur complet à 100%.

Les bases de CVE

Je profite de ce petit moment salé à propos du téléchargement des bases de CVE pour vous expliquer un peu ce que sont ces bases.

Ce sont simplement des listes de numéros de failles et les informations qui vont avec :

  • numéro de faille (e.g CVE-2021–44228)
  • produit affecté (exemple log4j)
  • version de départ (exemple 2 2.0-beta9)
  • version de fin (exemple 2.16.0)
  • sévérité au format LOW/MEDIUM/HIGH/CRITICAL (par exemple Log4Shell était critique.
  • sévérité au format "note /10" (log4shell était 10)

La base la plus grande (National Vulnerability Database) est au NIST, et on peut par exemple voir ce genre d’information :

Une capture d'écran de nvd.nist.gov qui montre la vulnérabilité log4shell avec son badge 10 Critique ainsi que les autres détails
La NVD

Mais ces derniers temps github, mais aussi Google pour ne citer qu’eux ont eu le droit de numéroter des CVE et donc de publier leurs bases, ce qui multiplie les sources pour le plugin dependency check.

Quelques retours d’expérience sur dependency-check

L’outil fait le job pour lequel il a été conçu et… c’est tout. J’ai déjà évoqué le fait que le rapport est complexe à exploiter pour la machine, mais c’est principalement car malgré une structure "globalement" stable, certaines bases de données ne donnent pas le résultat dans le même format et dependency-check ne fait pas vraiment le travail d’uniformiser l’output. Tout ce qui compte est que le HTML soit lisible, pas que le rapport soit exploitable par un outil d’automatisation.

D’ailleurs on remarquera qu’à cause de la différence entre les formats des bases de données, dependency-check ne met pas en avant la version qui corrige la CVE. Il faut donc lire le descriptif pour comprendre.

D’ailleurs dependency check ne se connectant pas aux dépôts maven (ou des autres techno), il est incapable de savoir que des versions plus récente existe. Il faut donc le croiser avec les rapports des plugins dependency-upgrade ou encore dependency-convergence.

D’ailleurs c’est aussi une faiblesse de dependency-check : il n’est pas rare que des dépendances transitives existent mais que vous même dépendiez d’une version non vulnérable. C’est une erreur de dependency convergence mais dependency-check ne se soucie pas que par exemple la version vulnérable ne sera même pas téléchargée : il considère que vous en dépendez.

Enfin, la syntaxe des fichiers d’exclusion est… verbeuse et parfois un peu complexe à gérer. Ce qui fait que certains faux positifs restent ad vitam dans les rapports car les retirer prend plus de temps que de les ignorer.

Petite note pour mvnrepository.com

Il y a quelques temps le site mvnrepository.com s’est mis à afficher les vulnérabilités des dépendances directement.

Le site mvnrepository.com sur la page qui présente les versions de apache-poi. Le tableau fait 5 colonnes et la seconde se nomme "vulnerabilities". Dans le cas de apache-poi on note que les versions supérieures à 4.1.1 jusqu'à la dernière en date (5.2.3) n'ont pas de vulnérabilités, cependant pour les précédents, la colonnes affiche un badge avec écrit en gras, rouge le nombre de vulnérabilités.
Exemple avec Apache POI

Cependant mvnrepository.com n’affiche pas TOUTES les vulnérabilités, en comparant avec les rapports fournis par dépendency-check et cyclonedx (ça vient), ma principale hypothèse est que ce site ne regarde pas toutes les bases.


  1. En vrai il a des plugins pour tous les outils de builds liés à java, y compris ant et gradle. Mais ne sachant pas les utiliser et ayant choisi de me limiter à un billet pour l’instant, ces plugins ne seront évoqués que dans cette note.
  2. Je pense à toi bitbucket pipelines et tes surprises surprenantes sur la gestion de ce qui est caché, pour combien de temps etc.

cyclonedx, BOM BOM BOM BOM

Nous l’avons vu au dessus, le rapport fourni par dependency-check est exploitable par l’humain mais pas par la machine. Et c’est un soucis, car en terme de réactivité, une machine surpasse l’humain.

Pour pouvoir être plus automatisable, le mieux c’est probablement de voir plus large que juste les CVE. Justement, il existe depuis longtemps dans le monde de l’entreprise le concept de "Software Bill Of Material", souvent abrégé SBOM.

Le SBOM consiste à lister dans des formats intéropérables l’ensemble des risques associés aux composants logiciels:

  • vulnérabilités
  • licences
  • copyright
  • compatibilité…

Et c’est là qu’arrive CyclonDX. Il s’agit d’un système de SBOM créé par l’OWASP, toujours eux.

Comme pour dependency check, il y a un plugin maven. Le but de ce plugin est de produire un Bill Of Material au format XML ou JSON. mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom suffira à le produire.

Le format étant structuré pour être traité par une machine, il suffit d’avoir un bon logiciel.

En parlant de bon logiciel…

Dependency-track pour tracker les dependency

L’OWASP (on ne les arrête plus), fournit donc un tool qui vous permettra de tirer le meilleur de votre Bill Of Material : dependency track. A ne pas confondre avec dependency-check, qui check et ne track pas.

dependency-track donc, est un service web autohébergeable qui se nourrit de votre BOM, des bases de données de vulnérabilités, des bases de licenses, des ressources déposées sur les principaux dépôts (pas que maven) et vous permet de monitorer l’état des lieux des dépendances de votre projets.

Comme c’est une interface Web, vous pouvez y mettre une authentification, avec une gestion par groupe. Ils sont compatibles avec les principaux SSO, donc pour les entreprises c’est assez cool.

Ensuite vous allez pouvoir suivre l’état de vos logiciels. Toutes les bases de données sont prises en compte.

Par contre il vous faudra tuner les choses car sinon trop de remontées inutiles sont faites, surtout si vous avez des dépendances optionnelles.

Surtout si vous n’êtes pas affectés par une vulnérabilité (dans le sens : vous avez bien la dépendance vulnérable mais vous n’utilisez pas la partie qui l’est), il suffit de le noter et de marquer votre logiciel comme non affecté. Le tout sera sauvegardé et n’importe qui pourra en tirer un rapport qui présente bien en terme administratif.


3 commentaires

Je me permet d’insister sur ce point, parce que pour moi, c’est un gros défaut (auquel on ne peut en général pas faire grand chose):

Par contre il vous faudra tuner les choses car sinon trop de remontées inutiles sont faites, surtout si vous avez des dépendances optionnelles.

Je trouve que ce genre d’outil reporte énormément (!) de faux positifs et de cas ou on ne peut, en tant que développeur tiers, pas faire grand chose. Deux exemples:

  • npm audit, qui a ce don de t’embêter pour une sous-dépendance de sous-dépendance de sous-dépendance, ce qui lié au fait que semver n’est pas compris par tout les développeurs JS rend la maintenance impossible (par exemple, il y a une faille dans la version 3.x d’une dépendance de dépenance, et on te conseille de passer à la 5.x, qui casse évidement le parent, donc il faut attendre la bonne volonté des devs du package parent). Voir à ce sujet https://overreacted.io/npm-audit-broken-by-design/
  • L’ami dependabot (maintenant désactivé par défaut?) de GitHub, qui est un peu intrusif et insistant (probablement parce que je reçois les notifications Github par email, donc ça ajoute au côté "intrusif"), même si il y a moyen de lui dire de se calmer.

Pour le coup, npm audit m’énerve le plus, parce qu’il est lancé par défaut pour tout npm install il n’y a pas moyen de lui demander d’arrêter, à ma connaissance.

+1 -0

Pour le coup, le cas de la dépendance transitive qui est effectivement vulnérable et que tu peux pas changer n’est pas un faux positif et vient surtout de la maintenance des logiciels, surtout sur JS où tout est surdécoupé en microlibs.

En java, le système d’exclusion permet d’éviter pas mal de soucis et on a énormément de libs qui ne dépendent que de peu de choses.

+0 -0

Pour le coup, npm audit m’énerve le plus, parce qu’il est lancé par défaut pour tout npm install il n’y a pas moyen de lui demander d’arrêter, à ma connaissance.

pierre_24

Hello,
Il existe une option pour un seul package https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities#installing-a-single-package et une autre pour l’installation globale https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities#installing-all-packages

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte