Skip to main content

Amélioration des tests de sécurité des projets Gradle basés sur Git grâce au fichier de verrouillage

Écrit par

Antonio Gomes

Blog illustrations Gradle

7 décembre 2020

0 minutes de lecture

Depuis un an, nous travaillons sans relâche à améliorer les tests des projets Gradle importés depuis des dépôts Git, afin de les rendre plus fiables, plus précis et plus évolutifs.

Nous avons compris que l’analyse d’un manifeste Gradle plutôt que d’un fichier de verrouillage Gradle serait une bataille sans fin, que nous finirions toujours par perdre. Tenter d’interpréter le modèle de complexité de Gradle en analysant un fichier build.gradle est une approche non déterministe qui repose sur de nombreuses hypothèses. Les configurations qui imposent strictement une version ou une version maximale pour une ou plusieurs dépendances, ou dont les versions sont définies dans d’autres fichiers, ne seraient pas toujours prises en compte. De plus, cette approche ne permettrait jamais de déclarer explicitement ce que Gradle va résoudre et utiliser dans différents contextes de configuration, comme les phases de compilation, de test ou d’exécution. Tout cela peut entraîner des résultats inexacts ou incomplets.

C’est pourquoi différents outils de gestion des dépendances s’appuient sur le verrouillage des dépendances pour aider les développeurs à obtenir des builds reproductibles. C’est notamment le cas de npm (package-lock.json), yarn (yarn.lock), RubyGems (Gemfile.lock) et, désormais, de Gradle avec gradle.lockfile.

Comment générer un fichier de verrouillage Gradle

Voici à quoi ressemble un fichier gradle.lockfile classique :

Fichier de verrouillage des dépendances Gradle affichant des avertissements concernant les fichiers générés et les versions verrouillées 2.12.1 de Log4j API et Core.

Il ne contient ni arborescence ni graphe. Il remplit plutôt son rôle en répertoriant toutes les dépendances directes et transitives utilisées, ainsi que leurs versions et les configurations auxquelles elles appartiennent.

Pour générer un fichier de verrouillage dans votre projet unique ou votre mono-dépôt (qui contient plusieurs sous-projets), modifiez votre fichier build.gradle en y ajoutant les instructions suivantes :

Éditeur build.gradle en thème sombre affichant la configuration du verrouillage des dépendances et une tâche pour résoudre et écrire les fichiers de verrouillage des dépendances

Comme vous pouvez le voir, nous demandons à Gradle de déclencher dependencyLocking pour toutes les configurations disponibles, par exemple annotationProcessor, compile, runtime, etc.

Une fois le code ajouté, Gradle pourra comprendre ce que nous voulons faire.

Dans cet exemple, nous avons une seule configuration. En général, cependant, nous pouvons en avoir plusieurs et obtenir un fichier de verrouillage par configuration. Pour disposer d’une source unique de vérité, voyons comment générer un seul fichier de verrouillage par projet.

Générer un fichier de verrouillage unique

Grâce à une fonctionnalité en avant-première de Gradle 7.0, déjà disponible pour les utilisateurs de Gradle 6.0 et versions ultérieures, nous pouvons générer un fichier gradle.lockfile unique par projet, qui contient tous les états de verrouillage des différentes configurations. Cette méthode utilisant un fichier de verrouillage unique deviendra la méthode par défaut à partir de Gradle 7.0.

Éditeur de code affichant le fichier settings.gradle avec l’aperçu de la fonctionnalité Gradle ONE_LOCKFILE_PER_PROJECT activé.

Une fois cette règle définie, il faut exécuter dans le terminal la commande gradle resolveAndLockAll --write-locks, qui générera le fichier de verrouillage ci-dessous :

Visual Studio Code affiche un projet Gradle et le fichier gradle.lockfile avec les entrées de dépendances, ainsi que la commande `gradle resolveAndLockAll --write-locks`.

Voici ce que nous pouvons constater :

  • chaque ligne représente toujours une dépendance unique au format GAV group:artifact:version.

  • chaque dépendance est associée à une liste de configurations dans lesquelles elle figure.

  • la dernière ligne, empty, contient la liste des configurations disponibles sans dépendance.

Comment le fichier de verrouillage Gradle vous simplifie la vie

Le verrouillage des dépendances peut éviter les erreurs inattendues causées par une dépendance transitive que vous ne maîtrisez pas lorsque vous utilisez des versions dynamiques (par exemple, 1.+ ou [1.0,2.0). C’est une situation fréquente qui peut survenir à tout moment en arrière-plan.

Voici un petit fichier build.gradle dans lequel nous déclarons une dépendance avec une version dynamique :

Éditeur de code en mode sombre affichant un fichier de build Gradle avec Java, Maven Central et une dépendance à un processeur d’annotations Log4j.

En exécutant la commande gradle -q dependencies, le résultat n’est ni 2.11 ni 2.14. Comme le montre l’image ci-dessous, Gradle a résolu les dépendances vers la version 2.13.

Sortie du terminal montrant la résolution des dépendances Gradle pour la configuration annotationProcessor, notamment Log4j core et API version 2.13.3.

En vérifiant les dépendances répertoriées dans le fichier de verrouillage, nous pouvons maintenant confirmer que le résultat de la commande correspond à l’état du fichier de verrouillage de l’application de notre exemple.

Capture d’écran d’un fichier de verrouillage des dépendances Gradle indiquant que les modifications manuelles peuvent interrompre la compilation, suivie d’entrées de dépendance Log4j.

Passons maintenant aux résultats !

Voici un cas où nous n’avons pas pu analyser le fichier build.gradle contenant des dépendances avec des versions dynamiques. Comparons les résultats en utilisant un fichier gradle.lockfile.

Tableau de bord des projets Snyk affichant le fichier build.gradle du dépôt unparsed-gradle-repo et son onglet Dépendances

Comme vous pouvez le constater, les résultats obtenus avec le fichier gradle.lockfile sont nettement meilleurs : nous avons pu identifier 24 dépendances contre 0 dans le cas précédent, y compris les dépendances directes et transitives, et signaler 33 problèmes au total !

Vue des dépendances du projet build.gradle présentant les tests du fichier de verrouillage Gradle, ainsi que les vulnérabilités et les problèmes de licence des packages répertoriés

Pour approfondir le verrouillage des dépendances dans Gradle, consultez la documentation officielle.

Nous espérons que cette fonctionnalité de Snyk vous plaira ! Vous n’avez pas encore de compte Snyk ? Inscrivez-vous gratuitement.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.