FlawOpen

flawopen.com/Traversal de rutas/Zip Slip

¿Qué es una vulnerabilidad Zip Slip?

Reference page
ELI5

Un archivo ZIP puede contener nombres como ../../outside.txt. Si el extractor confía en ellos, puede escribir fuera de la carpeta de destino; el límite son los permisos del proceso.

Por qué es fácil pasarla por alto

Extraer un archivo parece rutinario, pero quien crea un ZIP o TAR no confiable controla los nombres de sus entradas. Unir outputDir + entry.name sin validar la ruta permite escapar del directorio mediante el contenido del archivo.

VULNERABLE (conceptual)
for entry in zip_file:
    dest = os.path.join(output_dir, entry.name)
    write_file(dest, entry.read())
# entry.name podría ser "../../outside.txt"
COMPROBACIÓN DE CONTENCIÓN LÉXICA — no basta contra condiciones de carrera
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())

Esta comprobación impide escapes de ruta, incluidos nombres hermanos que comparten un prefijo de texto. Extrae en un directorio nuevo y privado; rechaza entradas symlink y contempla symlinks preexistentes o cambios concurrentes del sistema de archivos, que requieren API resistentes a condiciones de carrera o una biblioteca de extracción mantenida.

Preguntas frecuentes

Las API de archivos de Python ofrecen protecciones distintas

El par de código anterior es un ejemplo conceptual de extracción personalizada; no es el ZipFile.extractall() integrado de Python. La documentación de Python indica que ZipFile.extract() y extractall() intentan impedir escapes con rutas absolutas y .., pero aun así recomienda inspeccionar los archivos no confiables. zipfile.Path no sanea los nombres de los miembros, por lo que el código que lo usa debe validarlos. Para archivos TAR, los filtros de extracción llegaron en Python 3.12; en Python 3.14 el valor predeterminado pasó a ser filter="data". Establece ese filtro explícitamente en los runtimes compatibles cuyo valor predeterminado pueda ser menos restrictivo. Ni siquiera el filtro data bloquea todos los comportamientos inseguros o los riesgos de agotamiento de recursos. Extrae en un directorio temporal nuevo y privado y limita el tamaño del archivo, el número de miembros, el total descomprimido y el tiempo de procesamiento.

¿Las bibliotecas modernas de archivos comprimidos lo evitan automáticamente?

Algunas versiones incorporaron protecciones después de que el patrón se difundiera en 2018; otras no validan las rutas de forma predeterminada. Consulta la documentación de tu versión y valida cada entrada explícitamente.

Referencias

Véase también Path traversal (CWE-22): cómo funciona y cómo evitarlo en todos los lenguajes — flawopen.com Node.js path.join() no evita Path Traversal PHP include() y rutas controladas por el usuario Corregir path traversal con Python os.path.join()