Retour sur dependency-check, et son intégration dans Azure DevOps

Cela fait maintenant deux ans que je suis amené à utiliser dependecy-check quotidiennement. Il est temps de vous faire un petit retour sur cet outil, et son intégration dans Azure DevOps.


De quoi s'agit-il ?

OWASP dependency-check sert à identifier les dépendances vulnérables d'une application. Pour atteindre cet objectif, dependency-check doit scanner vos projets, et interroger l'API NVD afin de vérifier celles-ci.


Par où commencer ?

La documentation de dependency-check se trouve ici. Le scan d'une application pouvant être long, on préfèrera confier celui-ci à un serveur de builds.

Même si la documention n'en parle pas beaucoup, il existe une extension pour Azure DevOps. On peut la trouver sur le marketplace de Azure DevOps.

Après installation de celle-ci, il faudra veiller à se procurer une clé pour l'API NVD. Cela se passe ici.


QUID de la configuration ?

La configuration de dedendency-check ne se fait pas au niveau de l'extension, mais sein de chaque pipeline. J'opte habituellement pour les librairies d'Azure DevOps pour stocker la clé de l'API NVD, mais Azure KeyVault fait aussi très bien l'affaire.

Voici un petit exemple de paramétrage de la tâche dependency-check-build-task@6 via YAML:


  - task: dependency-check-build-task@6
    displayName: Dependency Check
    continueOnError: True
    inputs:
      projectName: $(product) $(version)
      scanPath: $(Build.BinariesDirectory)\bin
      additionalArguments: --nvdApiKey ${{ nvdApiKey }}}
      warnOnCVSSViolation: true


La documentation pour Azure DevOps, n'est malheureusement pas très fournie. Mais on peut modifier ou créer sa définition de build via Azure DevOps pour consulter l'ensemble de propriétés de la tâche dependency-check-build-task@6.

Voici quelques captures d'écran pour que vous vous fassiez une petite idée :

Options de la tâche dependency-check

Comme on peut le voir, beaucoup d'options sont disponibles. Certaines peuvent surprendre, comme le fait de pouvoir limiter la version du dependency-check utilisée. J'en parlerai un peu plus tard dans cet article. Au moment de livrer mes conclusions. D'autres permettent d'utiliser pour faire du "quality gate". Ce qui est beaucoup plus intéressant.

L’option continueOnError:true trouvera son explication dans la conclusion ;)

Les options de formats sont les plus intéressantes. Ce sont elles qui permettent de gérer la manière dont dependency-check remonte ses résultats. On peut distinguer deux usages :

  • Le format HTML. Celui-ci produit un fichier qui sera téléchargeable avec les artefacts de builds. Mais l'intégration s'arrêtera là.
  • Le format JUNIT : Qui peut être gérée par AzureDevOps et donc s'afficher telle une liste de tests unitaires. Avec une erreur par librairie comportant une faille connue.

Voici un exemple tiré du marketplace Azure DevOps :

List de tests liés à dependency-check


Quelques particularités liées à .net, et Azure DevOps ?

L'analyse d'une solution .net peut poser quelques difficultés à dependency-check.

Parmi celles-ci on en distinguera deux :

  • dependency-check ne sait pas se rendre compte qu'une application .net utilisant plusieurs technologies. Il n'ira regarder que la liste des librairies .net. Si vous utilisez du javascipt, il n'y fera pas attention.
  • dependency-check ne sait pas utiliser un fichier .sln. Il préfèrera avoir un masque de recherche du style *.csproj ou qu'on lui indique un dossier de DLL à scanner (seule solution si vous avez plusieurs solutions ou que vos projets incluent des projets VB.net).

Du côté d'Azure DevOps, je vous encourage vivement à ne pas utiliser dependency-check avec les agents autohébergés de Microsoft. On préfèrera utiliser un agent de build que l'on héberge soit même (sur un serveur on premise, ou dans Azure par exemple).

La raison est toute simple. dependency-check se connecte à l'API NVD afin de construire une base de données locale des vulnérabilités (cela prendra plusieurs minutes) :

  • Avec un agent que l'on héberge soit même, la base est actualisée lors de la première exécution de la journée. Les exécutions suivantes réutilisent ensuite la base.
  • Avec un agent autohébergé par Microsoft, il faudrait pouvoir utiliser les solutions de cache fournies par Azure DevOps. Malheureusement, la tâche dependency-check-build-task@6 ne semble pas fonctionner correctement quand on lui indique une autre localisation pour sa base que celle par défaut. Cette solution n'est donc pas viable.

Note : dependency-check est une application JAVA. Il faut donc disposer d'un JRE. OpenJDK fait très bien l'affaire.


Mon avis après deux ans

Dependency-check est une bonne solution tant que l'on ne se retrouve pas confronté a ses limites. Comme toute solution du genre, me direz-vous. Oui, mais voilà, on se retrouve encore avec une application qui n’est pas spécialisée dans le .net qui pense pouvoir répondre aux besoins des développeurs .net (oui, ce n'est pas la première fois que je rencontre ce genre de contexte).

Aujourd'hui, les développeurs .net ont des besoins beaucoup plus "pluriels". Ils n'utilisent pas qu'un seul format de projet, n'ont pas qu'un seul langage. Mais surtout, le premier fichier rencontré quand on utilise Visual Studio est un fichier .sln qui n'est pas utilisable ici.

À cela doivent s'ajouter quelques déconvenues :

  • À deux reprises, j'ai constaté que l'interface de gestion des packages nuget de Visual Studio m'indiquait que des dépendances comportaient des failles alors que denpendcy-check ne remontait aucune alerte.
  • Fin décembre, dependency-check m'a remonté une alerte sur une faille qu'il indique lui-même comme aillant été découverte en aout.
  • Durant un peu plus d'une une semaine en novembre dernier, dependency-check n'a pas été utilisable. Quelques erreurs dans dependency-check suite à son passage en version 9 qui ont provoquer quelques problèmes de disponibilité de l'API NVD. C'est dans ces moments que vous découvrez que l'on vous demande d'utiliser un outil Open source qui n'est maintenu que par un développeur. Malheureusement, celui-ci n'est accompagné par aucune entreprise.
  • Le passage en version 9 de dependency-check a été accompagné d'un breacking-change important. Il faut lui fournir une clé d'API NVD. En soi, ce n'est pas un problème. Par défaut, la tâche dependency-check télécharge toujours la dernière version de dependency-check avant de l'utiliser. Sans compter sur le gros bug cité un peu plus tôt qui, le jour où la version 9 a été publiée, il fallait modifier toutes les définitions de builds l'utilisant (quel bonheur, quelle joie). Même s’il est aujourd'hui possible de limiter la version de dependency-check utilisée, empêcheriez-vous la mise à jour d'un produit destiner à garantir la sécurité de vos applications ? De mon côté, j'ai beaucoup de mal à le concevoir.


Conclusion

En tant que développeur .net, je déconseille dependency-check. Un développeur JAVA y trouvera peut-être son bonheur, à condition de ne pas utiliser d'outils automatisant le déploiement et la mise à jour des outils de builds (ce que nous sommes tous amenés à faire un jour afin de gagner en efficacité).

À la place, je recommande Ment Bold (anciennement WhitSource). Celui-ci a en plus l'avantage de vous fournir un rapport relatif aux différentes licences utilisées ainsi que les risques associés. Cela fait quelque temps que je ne l’utilise plus régulièrement, mais j’en ai gardé un très bon souvenir.

Jérémy Jeanson

Comments

You have to be logged in to comment this post.