Dans les coulisses de la divulgation : la vulnérabilité Zip Slip
15 août 2018
0 minutes de lectureEn juin 2018, l’équipe de recherche de Snyk a découvert de nombreux cas exploitables de la vulnérabilité Zip Slip dans différents écosystèmes, touchant des milliers d’applications. Une vulnérabilité aussi répandue exige un processus de divulgation privée bien pensé, afin d’avertir les responsables des bibliothèques et des projets vulnérables avant toute divulgation publique. Mais comment détecter, corriger et divulguer une telle vulnérabilité à autant de personnes sans la rendre publique ? Cet article revient en détail sur les étapes que nous avons suivies, de la découverte à la divulgation, en passant par la création de pull requests correctives, et au-delà.
Il est important de préciser que Zip Slip n’est pas une vulnérabilité spécifique à un package ou à une bibliothèque en particulier, mais un type de vulnérabilité permettant l’écriture de fichiers arbitraires, extrêmement répandu dans de nombreux projets. Autre précision : Zip Slip n’est pas une vulnérabilité nouvelle à proprement parler. Ce type de vulnérabilité existe depuis de nombreuses années, voire des décennies, mais compte tenu de sa prévalence et du nombre d’exemples vulnérables découverts par notre équipe de sécurité, nous avons estimé qu’il était important de lui donner un nom, comme pour la vulnérabilité Zip Bomb.
Les débuts
Quoi de mieux que de commencer par le début ! Plus tôt en 2018, dans le cadre de nos recherches continues, nous avons identifié un schéma vulnérable dans la façon dont les clients FTP gèrent le téléchargement de dossiers et découvert une implémentation exploitable dans Apache Hive. Cela montre qu’une vulnérabilité connue, qui touchait les clients FTP dès 1990 (et même avant), existe toujours dans de nombreuses bibliothèques clientes FTP open source écrites dans différents langages. Nous avons ensuite poursuivi nos recherches et découvert d’autres schémas similaires dans des bibliothèques open source très utilisées.
Nous avons décidé de commencer par l’extraction d’archives. Lors de l’extraction de fichiers à partir d’une archive, une méthode d’attaque peut permettre de parcourir les répertoires. Une vulnérabilité de traversée de répertoires permet à un attaquant d’accéder à des parties du système de fichiers en dehors du dossier cible, où il devrait normalement être cantonné. L’attaquant peut alors écraser des fichiers exécutables, puis les lancer à distance ou attendre que le système ou un utilisateur les exécute, ce qui lui permet d’exécuter des commandes à distance sur la machine de la victime. Cette vulnérabilité peut également causer des dommages en écrasant des fichiers de configuration ou d’autres ressources sensibles, et peut être exploitée aussi bien sur les machines clientes (utilisateurs) que sur les serveurs.

Identifier les bibliothèques exploitables
L’équipe a commencé par examiner plusieurs exemples de code issus de bibliothèques open source populaires dans les écosystèmes Java, JavaScript et Go. Après quelques recherches seulement, et à notre grande surprise, nous avons découvert que plus de la moitié d’entre elles étaient vulnérables. Autrement dit, plus de la moitié des bibliothèques examinées au départ ne nettoyaient ni ne validaient les noms de fichiers présents dans les archives. Une exploitation pouvait ainsi entraîner l’écrasement arbitraire de fichiers. La liste complète est disponible ici.
Il est vite apparu que certains langages étaient plus touchés que d’autres par cette vulnérabilité, tandis que dans d’autres, elle était pratiquement inexistante. Examinons quelques écosystèmes pour voir comment leurs différentes approches de la gestion des archives ont influé sur la prévalence de la vulnérabilité Zip Slip.
Zip Slip en Java
L’environnement d’exécution Java, par exemple, fournit les classes Zip dans le langage de base, ce qui permet aux développeurs d’écrire du code qui lit des archives et en extrait des fichiers ZIP. Des bibliothèques Java populaires, comme Apache Commons-Compress, prennent en charge d’autres formats, ce qui élargit le problème. Cependant, il n’existe pas d’API simple permettant d’effectuer cette opération en un seul appel, d’où la multiplication des implémentations dans l’écosystème, dont la plupart étaient vulnérables.
Zip Slip en Python
Python, en revanche, fournit la classe zipfile dans son environnement d’exécution de base (zipfile.extractall()), et n’est pas vulnérable. Ainsi, au cours de notre analyse des dépôts Python, nous avons systématiquement trouvé des implémentations sécurisées.
Il convient de noter que le module tarfile de Python est toutefois touché. En effet, son implémentation dans l’environnement d’exécution de base est vulnérable. Lorsqu’une vulnérabilité se trouve dans l’environnement d’exécution de base d’un langage plutôt que dans une bibliothèque, elle peut être corrigée automatiquement lors de la mise à niveau vers une version plus récente du langage, sans qu’il soit nécessaire de modifier l’application ou ses dépendances. C’est souvent plus courant que la mise à niveau vers une version plus récente d’une dépendance, sauf, bien sûr, si vous utilisez un outil comme Snyk, qui vous aide à le faire ! (Désolé, je n’ai pas pu résister à cette autopromotion éhontée !)
Qui d’autre est vulnérable ?
La gravité des répercussions sur certains des principaux langages et bibliothèques était vite devenue évidente. Nous avons donc décidé de concentrer nos efforts sur les projets open source qui n’étaient pas des bibliothèques. Nous avons analysé les projets Java open source les plus populaires hébergés sur GitHub et contenant du code de manipulation d’archives.
Nous avons rapidement constaté que la plupart des implémentations étaient vulnérables. C’était particulièrement fréquent en Java, où nous avons vu les mêmes implémentations vulnérables réutilisées. Cela laissait penser que ces extraits vulnérables étaient repris d’autres projets, de la documentation ou de communautés.
StackOverflow : le supermarché des vulnérabilités
Après avoir analysé la plus grande ressource à la disposition des développeurs adeptes du copier-coller, nous avons vite compris que notre hypothèse était juste. Nous avons trouvé de nombreuses questions sur la meilleure façon d’extraire des fichiers d’archives par programmation. Nous avons également constaté que presque toutes les réponses sur StackOverflow étaient vulnérables. Plus inquiétant encore, toutes les réponses vulnérables avaient un nombre de votes positifs qui ferait pâlir n’importe quel bâton de sécurité. Voici quelques-unes de nos préférées, avec deux commentaires qui nous ont égayé la journée :
« Utilitaire pour décompresser une archive entière dans un répertoire en Java » On est en 2011 et il n’existe même pas de bibliothèque tierce (courante) pour extraire un ZIP en Java en un seul appel ? WTF
Quelle est une bonne bibliothèque Java pour compresser/décompresser des fichiers ? Très bien, alors faites en sorte que la bibliothèque prenne en charge à la fois les fichiers et les flux. C’est une perte de temps pour tout le monde — moi, vous, la personne qui pose la question et tous ceux qui tomberont dessus via Google — de devoir chacun implémenter nos propres utilitaires Zip. Il y a le principe DRY, et il y a DROP : Don’t Repeat Other People (ne répétez pas le travail des autres).
Comment décompresser des fichiers par programmation sur Android ?
Une fois la divulgation privée lancée, notre équipe de sécurité a poursuivi ses recherches et découvert d’autres exemples de cette vulnérabilité. Voici quelques chiffres clés pour résumer nos découvertes :
12 bibliothèques vulnérables. 5 pull requests correctives ouvertes et fusionnées.
5 bibliothèques sans API de haut niveau.
Des milliers d’applications avec l’implémentation vulnérable (pas nécessairement exploitable)
Est-ce mal de s’enthousiasmer ?
Le rôle d’un chercheur en sécurité consiste à trouver des vulnérabilités, à combler les failles et à contribuer à rendre le monde logiciel plus sûr, pour que des milliards de personnes puissent avoir confiance dans la réussite des transactions commerciales essentielles, chaque seconde de chaque jour. Cela ne veut pas dire que la découverte d’une vulnérabilité critique n’est pas satisfaisante. Les moments d’euphorie où l’on trouve enfin la solution donnent l’élan nécessaire pour rester concentré pendant les périodes moins enthousiasmantes. Savoir qu’une découverte intéressante ou une faille pourrait se trouver juste au tournant motive à passer des jours, des semaines et des mois à chercher. Trouver une vulnérabilité procure une joie semblable à celle d’un développeur qui finit par trouver la cause profonde d’un bug complexe. Ou qui repense une application pour en doubler les performances ou en tripler l’évolutivité.
Lorsque nous avons découvert le premier cas de vulnérabilité Zip Slip dans un grand projet, nous étions très enthousiastes. C’était notre moment eurêka. Mais en découvrant que toutes les autres applications avaient une implémentation vulnérable, nous avons été extrêmement surpris. Nous avons compris que cette vulnérabilité ne touchait pas seulement quelques applications, mais un grand nombre de projets dans différents écosystèmes.
Passer au crible toutes les données, comprendre pourquoi certains langages étaient plus touchés que d’autres et comment des extraits de code vulnérables se propageaient dans les projets open source : tout cela était passionnant et instructif. C’était aussi une tâche de recherche très différente de la chasse aux vulnérabilités. Le véritable travail difficile a commencé avec la divulgation et l’aide apportée aux projets pour corriger leur code vulnérable. Repérer un maillon faible est relativement facile ; renforcer tous les maillons, c’est difficile.
La divulgation
Nous avons suivi le processus de divulgation responsable et fixé la date de divulgation publique au 5 juin. Les responsables des projets disposaient ainsi de 60 jours pour corriger les problèmes. Tous les projets vulnérables que nous avions repérés étant open source, l’activité dans leurs dépôts, comme les commits et les pull requests, était elle aussi publique et visible. Il était donc essentiel de trouver un équilibre entre un délai raisonnable pour corriger les problèmes et le risque de les exposer largement au public, ce qui aurait mis en danger les projets non corrigés.
Nous avons d’abord contacté les responsables des bibliothèques les plus largement adoptées qui présentaient la vulnérabilité, afin de les en informer. Nous avons envoyé un premier lot d’e-mails à 10 responsables. Certains ne savaient même pas que la bibliothèque qu’ils avaient créée à l’origine pour leur propre usage était devenue l’une des plus populaires pour l’extraction d’archives. Parmi ces 10 bibliothèques, les responsables de 5 d’entre elles nous ont demandé de les aider à corriger le problème. Nous avons donc ouvert des pull requests correctives (plexus archiver, mholt/archiver, adm-zip, unzipper et zip4j).

Après avoir communiqué avec les responsables des bibliothèques, nous sommes passés aux projets touchés qui avaient implémenté leur propre logique d’extraction au lieu d’utiliser une bibliothèque centralisée. Ce code avait probablement été créé de toutes pièces ou copié-collé depuis de la documentation, StackOverflow ou d’autres projets OSS. Dans tous ces cas, du code vulnérable risquait de se propager. Une fois la liste établie, nous avons vite compris qu’elle était trop longue pour contacter tout le monde sans risquer une fuite publique, que ce soit par l’intermédiaire des corrections apportées aux projets ou de personnes irresponsables qui auraient diffusé l’information sans en comprendre les conséquences. Nous avons d’abord ciblé les grands projets, en commençant par Apache, qui comptait 15 projets avec des implémentations vulnérables.
Après un échange avec Mark J Cox, membre fondateur de l’Apache Software Foundation et responsable de la sécurité chez Apache, nous avons créé un tableur collaboratif répertoriant tous les projets potentiellement concernés, afin qu’ils puissent les examiner en interne et déterminer lesquels étaient exploitables. Qu’ils soient exploitables ou non, il est toujours recommandé de corriger une implémentation vulnérable, et presque tous l’ont fait, en raison du risque qu’elle soit utilisée ultérieurement ou copiée dans d’autres projets. Apache Hadoop, Storm, Hive, Maven et Ant ont été déclarés concernés. Des CVE publiques (CVE-2018-8008, CVE-2018-8009) ont été créées au moment de la divulgation publique, ainsi qu’une annonce Maven Zip Slip sur le site Apache. Mark s’est montré extrêmement coopératif et nous a aidés à découvrir et corriger le problème, puis à communiquer à ce sujet auprès de chacun des projets Apache concernés.
Nous avons également contacté Pivotal (l’intégration zip, corrigée dans les deux jours suivant la divulgation !), Oracle, Google, OWASP Dependency-Check (corrigé dans la journée suivant la divulgation !) et bien d’autres.
Enfin, nous souhaitions informer en privé tous les autres projets concernés. Comme il y avait trop de projets pour qu’une seule équipe puisse les tester et les trier manuellement, nous avons choisi d’automatiser le processus en avertissant les responsables de maintenance des risques potentiels et en les invitant à vérifier eux-mêmes si leur projet était réellement exploitable. Bien sûr, cette divulgation groupée à grande échelle comporte un risque supplémentaire : attirer l’attention du public. L’un des projets non vulnérables s’est tourné vers Twitter, ce qui a nécessité des échanges privés supplémentaires pour obtenir la suppression de la publication.
Au-delà de la divulgation publique
Lorsque le problème a été rendu public, nous avons publié une page d’information présentant notamment des exemples de vulnérabilités et des correctifs suggérés. Nous avons créé un dépôt GitHub collaboratif pour informer la communauté des bibliothèques et projets concernés, et lui permettre également d’y contribuer en ajoutant ceux que nous n’avions pas recensés. Au cours du mois dernier, plusieurs bibliothèques et projets ont été ajoutés, notamment closure, sharpziplib et quazip.
Si vous souhaitez en savoir plus sur la divulgation de Zip Slip, obtenir des conseils supplémentaires sur la divulgation d’une vulnérabilité ou demander l’aide de Snyk pour une divulgation privée, écrivez à security@snyk.io : nous serons ravis de contribuer à rendre l’open source plus sûr, un commit à la fois.
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.
