exarch : la vulnérabilité liée aux liens symboliques que nous avons signalée
GHSA-9r5q-fvpf-p55p : une archive TAR ou ZIP pouvait écrire des fichiers en dehors du dossier d'extraction en exploitant un lien symbolique déjà présent. Ce qu'a trouvé Liam Giannini de Webcracy, et pourquoi mettre à jour exarch vers la 0.8.0 ou une version ultérieure.

Extraire une archive semble l'opération la plus anodine du monde : on choisit un dossier, on ouvre le ZIP, les fichiers atterrissent là. Mais quand l'archive vient de l'extérieur, envoyée par un utilisateur, téléchargée depuis un service tiers, jointe à un e-mail, décider où finissent les fichiers devient une question de sécurité. Une archive conçue à cet effet peut tenter d'écrire en dehors du dossier choisi : dans des fichiers de configuration, dans les scripts que le serveur exécute au démarrage, dans le dossier d'un autre utilisateur.
exarch est une bibliothèque conçue précisément pour l'empêcher. Son cœur est écrit en Rust (exarch-core) et elle est aussi distribuée sous forme de paquet Python (exarch) et Node.js (exarch-rs). Le README la présente comme une alternative sûre à des bibliothèques comme tarfile en Python et tar-fs en Node.js, qui ont un long historique de vulnérabilités précisément de ce type. La promesse centrale est unique : les fichiers de l'archive restent dans le dossier de destination.
À partir de la version 0.6.1, et jusqu'à la 0.8.0 exclue, cette promesse pouvait être contournée. C'est le défaut décrit dans l'avis GHSA-9r5q-fvpf-p55p, publié le 2 novembre 2026 et corrigé dans exarch 0.8.0. C'est nous qui l'avons signalé : la découverte est de Liam Giannini (Liam-G sur GitHub), hacker éthique et cofondateur de Webcracy. Nous remercions le mainteneur d'exarch, qui a confirmé le problème et publié la correction en quelques jours.
Webcracy et la sécurité informatique
Webcracy ne s'occupe pas seulement de sites web et d'applications. La sécurité informatique est une partie centrale de notre travail : tests d'intrusion, revue de code, analyse des configurations, et recherche sur les bibliothèques et programmes open source que nous et nos clients utilisons chaque jour. Liam travaille comme hacker éthique : il cherche les failles avec les mêmes méthodes qu'un attaquant, mais avec l'objectif inverse. Ce qu'il trouve est signalé en privé à ceux qui peuvent le corriger, et rendu public seulement une fois la correction disponible. C'est ce qu'on appelle la divulgation responsable, et c'est la démarche que nous avons suivie ici aussi, comme pour la vulnérabilité de FreeScout signalée en octobre.
Ce qui se passait pendant l'extraction
Pour comprendre le problème, il faut deux ingrédients.
Le premier est un lien symbolique, un élément du système de fichiers qui se comporte comme un dossier mais pointe en réalité vers un autre emplacement. Avec sa configuration par défaut, exarch refuse les liens symboliques contenus dans l'archive : c'est l'une des protections classiques contre les archives malveillantes. Mais elle ne tenait pas compte d'un cas différent : un lien symbolique déjà présent dans le dossier de destination, avant même l'extraction. Cela arrive plus souvent qu'on ne le pense : dossiers partagés, mises à jour extraites par-dessus une installation existante, environnements où uploads ou cache pointent vers un autre disque.
Le second ingrédient est un cache des dossiers créés. Pour ne pas répéter les mêmes contrôles pour chaque fichier, exarch mémorisait les dossiers qu'elle avait déjà créés pendant l'extraction et les considérait comme fiables. Le problème, c'est que la fonction Rust utilisée pour les créer, create_dir_all, renvoie un succès même lorsque le chemin existe déjà et qu'il s'agit d'un lien symbolique vers un dossier. exarch enregistrait donc comme « dossier créé par moi » un lien qui menait en réalité ailleurs.
Il suffisait à l'attaquant d'une archive contenant deux entrées tout à fait ordinaires : un dossier redirect/ et un fichier redirect/pwned.txt. Si redirect existait déjà dans la destination comme lien vers un dossier externe accessible en écriture, la première entrée faisait entrer le lien dans le cache des dossiers fiables. Au moment de valider la seconde entrée, exarch sautait la résolution du chemin parent, puisqu'il était fiable, et aussi celle du chemin complet, puisque l'archive ne contenait aucun lien symbolique. Le flag O_NOFOLLOW utilisé à l'ouverture ne protège que le dernier composant du chemin, pas les dossiers intermédiaires. Résultat : l'extraction se terminait avec succès et le fichier apparaissait dans outside/pwned.txt, en dehors du dossier choisi, avec le contenu décidé par celui qui avait préparé l'archive.
Le problème concernait aussi bien les TAR que les ZIP, avec la configuration de sécurité par défaut. L'extraction des fichiers 7z, en revanche, n'était pas vulnérable, car par choix de conception elle n'utilisait pas le cache des dossiers dans la validation des chemins.
Quelle gravité
L'impact concret dépend de l'endroit où tourne l'application. Dans le pire des cas, il s'agit d'une écriture arbitraire de fichiers en dehors de la destination, limitée seulement par les permissions du processus. Avec l'option skip_duplicates = false, qui autorise l'écrasement, des fichiers existants accessibles via le lien pouvaient aussi être tronqués ou remplacés. Les conséquences peuvent alors aller de la modification de configurations à la persistance d'un attaquant, de l'interruption d'un service à l'exécution de code, lorsque le fichier écrit est ensuite lu ou exécuté par un autre composant.
Il y a toutefois une condition nécessaire : le lien symbolique doit déjà se trouver dans la destination, et l'attaquant doit en connaître le nom. C'est pourquoi la gravité est modérée, dans la catégorie CWE-59, résolution incorrecte des liens avant l'accès aux fichiers. Modérée ne veut pas dire marginale pour autant : le défaut touche la seule garantie pour laquelle on choisit une bibliothèque comme exarch.
Comment nous l'avons vérifié
Le problème est apparu à la lecture du code source d'exarch 0.6.1, en suivant le parcours d'une entrée de l'archive depuis le cache des dossiers (DirCache) jusqu'à la validation dans SafePath et à l'ouverture finale du fichier. Pour le confirmer, Liam a écrit deux tests de régression, un pour TAR et un pour ZIP, qui construisent l'archive en mémoire et l'extraient dans des dossiers temporaires créés à cet effet, sous Linux avec Rust 1.98.0. Sur la version vulnérable, les deux tests échouaient, car l'extraction réussissait et le fichier sortait de la destination.
Avec le signalement, nous avons aussi préparé une correction minimale : cesser d'utiliser l'appartenance au cache comme preuve de sécurité dans la validation des TAR et ZIP, en les alignant sur ce que faisait déjà le code 7z. Avec cette modification, les deux tests de régression passaient, tout comme les 801 tests unitaires et les 136 tests d'intégration existants.
La correction dans la 0.8.0
Le mainteneur est allé au-delà du correctif minimal. Dans la pull request #816, incluse dans la version 0.8.0, le cache a été supprimé et remplacé par un contrôle qui examine avec lstat chaque composant du chemin sous la destination, pour chaque fichier écrit. Le chemin parent est résolu à chaque fois, sauf lorsqu'il coïncide avec la racine de la destination. La correction s'applique aux TAR, ZIP et 7z, y compris aux modes d'extraction atomique.
Il y a un changement de comportement à connaître : par défaut, l'extraction échoue désormais s'il y a un lien symbolique quelconque dans la destination, même un lien qui pointe à l'intérieur de la destination elle-même. Ceux qui en ont besoin peuvent les réactiver avec l'option dédiée aux liens symboliques, et dans ce cas ils ne sont acceptés que s'ils restent à l'intérieur du dossier de destination. Un lien symbolique utilisé comme dossier de destination lui-même reste autorisé.
La pull request mentionnait ouvertement une limite résiduelle : un contrôle basé sur les chemins laisse une fenêtre temporelle entre la vérification et l'écriture, exploitable par quelqu'un qui dispose déjà d'un accès en écriture à la destination pendant l'extraction. La version 0.9.0, sortie le 5 novembre, comprend parmi d'autres modifications l'ancrage des écritures à des descripteurs de répertoire, qui est la solution recommandée pour ce cas. C'est un excellent exemple de la manière dont un signalement peut devenir l'occasion de renforcer tout un sous-système, et pas seulement de boucher un trou.
Que faire si vous utilisez exarch
Si vous utilisez exarch-core, le paquet Python exarch ou le paquet npm exarch-rs dans une version antérieure à la 0.8.0, mettez à jour. Comme la 0.9.0 ajoute d'autres protections sur l'écriture des fichiers, mieux vaut passer directement à la dernière version disponible, en vérifiant les changements d'API incompatibles indiqués dans les notes de version. Après la mise à jour, vérifiez aussi que vos extractions n'échouent pas à cause de liens symboliques légitimes dans la destination : c'est le nouveau comportement par défaut, et le choix le plus sûr est d'extraire dans un dossier vide et dédié.
Ce conseil vaut d'ailleurs pour n'importe quelle bibliothèque d'extraction, pas seulement pour exarch : extrayez les archives qui viennent de l'extérieur dans un dossier neuf, vide, créé par votre propre processus, avec un utilisateur qui n'a que les permissions indispensables. Ainsi, même un défaut comme celui-ci ne trouve aucun lien tout prêt à exploiter.
Pourquoi nous faisons de la recherche sur les logiciels open source
Une grande partie des logiciels qui tournent dans les entreprises, y compris dans celles qui pensent ne pas en utiliser, est faite de bibliothèques open source comme exarch, souvent maintenues par une seule personne ou par de petits groupes. Le code est public, mais quelqu'un doit le lire avec les yeux de celui qui veut le casser. Consacrer du temps à la revue de ces projets et signaler de manière responsable ce que nous trouvons, c'est notre façon de contribuer, et aussi de savoir précisément ce que nous mettons en production pour nos clients.
Si votre application accepte des fichiers envoyés par les utilisateurs, traite des archives, des documents ou des images venant de l'extérieur, ou n'a simplement jamais été examinée par quelqu'un qui cherche les failles, parlons-en volontiers. Notre travail de test d'intrusion commence justement là : lire le code et la configuration, comprendre où une donnée n'est pas contrôlée, et vous dire précisément ce que nous avons vérifié et ce que nous n'avons pas vérifié.
VOUS AVEZ UN PROJET?
Discutons de comment nous pouvons aider votre entreprise avec des solutions numériques sur mesure.
CONTACTEZ-NOUS