FlawOpen

flawopen.com/Traversal de chemin/Zip Slip

Qu’est-ce qu’une vulnérabilité Zip Slip ?

Reference page
ELI5

Une archive ZIP peut contenir un nom comme ../../outside.txt. Si l’extracteur lui fait confiance, il peut écrire hors du dossier cible, dans les limites des droits du processus.

Pourquoi le problème passe inaperçu

L’extraction semble banale, mais l’auteur d’une archive ZIP ou TAR non fiable contrôle les noms de ses entrées. Concaténer outputDir + entry.name sans vérifier le chemin permet de sortir du dossier via le contenu de l’archive.

VULNERABLE (conceptual)
for entry in zip_file:
    dest = os.path.join(output_dir, entry.name)
    write_file(dest, entry.read())
# entry.name peut être "../../outside.txt"
VÉRIFICATION DE CONFINEMENT LEXICAL — insuffisante contre les conditions de course
root = os.path.realpath(output_dir)
os.makedirs(root, exist_ok=True)
for entry in zip_file:
    dest = os.path.realpath(
      os.path.join(root, entry.name)
    )
    try:
        inside_root = os.path.commonpath([root, dest]) == root
    except ValueError:
        inside_root = False
    if not inside_root:
        raise ValueError("Unsafe entry path")
    write_file(dest, entry.read())

Ce contrôle bloque les sorties du répertoire, y compris les chemins frères partageant un préfixe textuel. Extrayez dans un répertoire neuf et privé ; refusez les entrées symlink et tenez compte des symlinks préexistants ou des modifications concurrentes du système de fichiers, qui nécessitent des API résistantes aux courses ou une bibliothèque d’extraction maintenue.

Questions fréquentes

Les API d’archives Python ont des protections différentes

La comparaison de code ci-dessus est un exemple conceptuel d’extraction personnalisée ; elle ne correspond pas à la méthode intégrée ZipFile.extractall() de Python. La documentation indique que ZipFile.extract() et extractall() tentent d’empêcher les sorties du répertoire via des chemins absolus et .., mais recommande tout de même d’inspecter les archives non fiables. zipfile.Path n’assainit pas les noms des membres : le code appelant doit les valider. Pour les archives TAR, les filtres d’extraction ont été ajoutés dans Python 3.12 ; Python 3.14 a défini filter="data" comme valeur par défaut. Définissez explicitement ce filtre sur les versions compatibles dont la valeur par défaut peut être moins restrictive. Même le filtre data ne bloque pas tous les comportements dangereux ni les risques d’épuisement des ressources. Extrayez dans un nouveau répertoire temporaire privé et limitez la taille de l’archive, le nombre de membres, le volume total décompressé et le temps de traitement.

Les bibliothèques d’archives récentes bloquent-elles cela automatiquement ?

Certaines versions ont ajouté des protections après la médiatisation de ce schéma en 2018 ; d’autres ne valident pas les chemins par défaut. Vérifiez la documentation de votre version et validez explicitement chaque entrée.

Références

À voir aussi Traversée de répertoires (CWE-22) : fonctionnement et prévention dans tous les langages — flawopen.com Node.js path.join() ne bloque pas Path Traversal PHP include() et chemins contrôlés par l’utilisateur Corriger le path traversal avec Python os.path.join()