← retour aux snippets

archives: extraction sécurisée (éviter path traversal)

Vérifier les chemins avant extraction d'une archive zip/tar.

python security #zip#tar#security

objectif

Vérifier les chemins avant extraction d’une archive zip/tar.

code minimal

from zipfile import ZipFile
from pathlib import Path
from tempfile import TemporaryDirectory

def is_within_directory(base: Path, target: Path) -> bool:
    try:
        base_resolved = base.resolve(strict=False)
        target_resolved = target.resolve(strict=False)
        return str(target_resolved).startswith(str(base_resolved) + "/")
    except Exception:
        return False

def safe_extract_zip(zip_path: Path, dest: Path):
    with ZipFile(zip_path) as z:
        for m in z.infolist():
            out_path = dest / m.filename
            if not is_within_directory(dest, out_path):
                raise ValueError("path traversal détecté")
        z.extractall(dest)

with TemporaryDirectory() as tmp:
    root = Path(tmp)
    zpath = root / "t.zip"
    with ZipFile(zpath, "w") as z:
        z.writestr("ok.txt", "OK")
        z.writestr("../evil.txt", "nope")
    try:
        safe_extract_zip(zpath, root / "out")
    except ValueError:
        print(True)  # attendu: True (bloqué)

utilisation

print(True)

variante(s) utile(s)

# Variante tar: parcourir getmembers() et vérifier les noms
print(True)

notes

  • Toujours valider les chemins d’archive avant extraction.
  • Refusez les chemins absolus et ceux contenant ”..”.