Mon pipeline dependency-check échoue … et après ?
Dans cet article je présente comment je traite les vulnérabilités qui sont remontées par mon pipeline dependency-check.

Sonar peut lui aussi les remonter :

Une boucle de test rapide
N’utilisez pas votre CI pour tester des montées de version hasardeuse, vous perdrez beaucoup de temps inutilement. Personnellement j’utilise ces 3 plugins maven :
- dependency-check-maven : permet de générer un rapport identique à celui de la CI (mais plus rapide car il cache la base de données des vulnérabilités en local) ;
- maven-dependency-plugin : permet d’avoir l’arbre de dépendance et faire la chasse aux dépendances transitives ;
- versions-maven-plugin : permet de connaitre les dernières versions des dépendances mais bien souvent https://mvnrepository.com/ reste très efficace.
Ces plugins peuvent être ajouté dans le pom.xml comme ceci :

(1) Notez ici que le build va échouer si une vulnérabilité > 7 est présente.
(2) Notez aussi que son exécution est attachée à l’étape verify et peut être lancé via «
mvn verify »
ou bien en ligne de commande ainsi :
mvn -s C:\Users\me\settings.xml org.owasp:dependency-check-maven:12.0.1:check
mvn -s C:\Users\me\settings.xml org.apache.maven.plugins:maven-dependency-plugin:3.8.1:tree
mvn -s C:\Users\me\settings.xml org.codehaus.mojo:versions-maven-plugin:2.18.0:display-dependency-updates
Mes 5 étapes pour gérer efficacement les vulnérabilité
Maintenant que je peux tester efficacement ma gestion de dépendances voici les 3 étapes majeures que j’utilise lorsque j’ai beaucoup de vulnérabilités :
1 – Corriger les dépendances de frameworks principaux :
Ces frameworks (spring-boot notamment) tirent beaucoup de dépendances, commencez par eux.
Un œil sur dependency:tree, un autre sur version-maven-plugin et un troisième sur https://mvnrepository.com/ vous permet de tenter une montée de version mineure (càd 2.5.4 -> 2.5.9 mais pas vers 2.6.3).
Pas à pas vérifiez, faites un clean, un compile, un dependency-check
(on se garde les tests qu’une fois satisfait de la dépendance trouvée).
2 – Corriger les dépendances directes :
Les dépendances directes sont celles définies dans le pom.xml.
3 – Corriger les dépendances indirectes :
Les dépendances indirectes ou transitives sont les dépendances des dépendances.
spring-cloud-starter-netflix-zuul tire commons-io et guava
Dans cet exemple spring-cloud-starter-netflix-zuul n’a pas de version plus récente que la 2.2.10.RELEASE et tire common-io de version 2.4 alors qu’une version 2.11.0 corrigée existe.
Le plus souvent on peut les gérer en jouant avec les excludes ainsi :

Nous pouvons les gérer aussi en utilisant la partie du pom.xml pour spécifier manuellement une version.
Pour les dépendances de spring-boot, on peut surcharger les properties comme ceci : <log4j2.version>2.24.3</log4j2.version>
ou <postgresql.version>42.7.5</postgresql.version>
Astuce : les properties spring-boot peuvent être trouvés ici : https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/3.4.2/spring-boot-dependencies-3.4.2.pom
D’autres explications ici : https://www.baeldung.com/spring-boot-override-dependency-versions
4 – Pas de solution
Surtout ne désactivez pas le pipeline ni autorisez pas les échecs car cela pourrait cacher une vulnérabilité plus importante qui pourrait apparaitre : « un train peut en cacher un autre ».
Je recommande 2 actions :
Partager ce risque avec le RT / CP et le client.
- Evaluez le risque, faites-vous potentiellement aider (votre chef de projet contactera le responsable de sécurité si nécessaire). Ce risque peut être pris d’un commun accord car l’exploitation est non applicable
ou très difficilement applicable
- Proposez des évolutions à votre client pour ne pas conserver ces vulnérabilités (de nouvelles s’ajouteront).
Rajouter une exception dans le fichier dependency_check_suppressions.xml en utilisant le rapport html
5 – Compiler, tester, commiter
Le compilateur détecte la majorité des erreurs, mais vos tests unitaires et d’intégration sont indispensables pour identifier les non régressions. Prévoyez aussi de lancer l’application localement, le classloader
peut détecter des mauvaises dépendances surtout si vous avez joué aux apprentis sorciers avec les excludes. Enfin, des tests en qualification sont toujours fortement recommandés (orienter les cas d’usage pour utiliser
les librairies).
Attention, nous avons vu ici différentes manières de gérer des dépendances ayant des vulnérabilités. Il est important de comprendre que jouer avec des excludes ou ignorer une vulnérabilité ne sont
que des solutions temporaires : on s’achète du temps et tôt ou tard il faudra utiliser des dépendances maintenues ou à jour. Car nous l’avons vu avec log4shell, même une librairie théoriquement non
exposée peut être un vecteur d’attaque inattendu et très dommageable.