tarfile extraction_filter: extrae TAR con seguridad

Publicado el: 08/10/2026
Tempo de leitura: 6 minutos
Archivos protegidos que representan extracción segura de TAR con Python

Los archivos TAR se utilizan en copias de seguridad, distribución de software, canalizaciones de datos, contenedores y procesos de despliegue. El módulo tarfile de Python permite leerlos y extraerlos con facilidad, pero una extracción procedente de una fuente externa no debe tratarse como una simple copia de archivos. Un TAR manipulado puede intentar escribir fuera del directorio de destino, crear enlaces peligrosos, conservar permisos no deseados o sobrescribir archivos sensibles. La función extraction_filter permite definir una política explícita para decidir qué miembros son aceptables.

En esta guía aprenderás a usar los filtros integrados, crear reglas personalizadas, limitar recursos, trabajar en un directorio temporal y probar los casos de riesgo más importantes.

Por qué un TAR necesita validación

Cada miembro contiene nombre, ruta, tipo, permisos, propietario, grupo, tamaño y, en algunos casos, destino de enlace. Esos valores provienen del propio archivo. Un nombre como ../../config.py intenta salir de la carpeta prevista. Una ruta absoluta puede apuntar a una ubicación del sistema. Un enlace simbólico puede redirigir una escritura posterior a otro lugar.

Por eso, un TAR desconocido debe considerarse una entrada estructurada que necesita validación. El flujo seguro requiere un destino aislado, comprobación de rutas, límites de tamaño, lista de tipos permitidos y una respuesta clara cuando una entrada se rechaza.

Usar el filtro data

Para archivos que contienen datos comunes, la política data suele ser el mejor punto de partida.

from pathlib import Path
import tarfile

archivo = Path("copia.tar.gz")
destino = Path("datos_extraidos")
destino.mkdir(parents=True, exist_ok=True)

with tarfile.open(archivo, "r:gz") as tar:
    tar.extractall(destino, filter="data")

El filtro se aplica mientras se evalúa cada miembro. Puede rechazar entradas inseguras o normalizar metadatos que no deberían conservarse en una importación de datos.

data, tar y fully_trusted

La política data favorece una extracción orientada a archivos de datos. La política tar conserva más características tradicionales del formato. fully_trusted es permisiva y solo debe usarse cuando el archivo sea realmente confiable, se haya generado en un entorno controlado y necesite mantener semántica avanzada del TAR.

Para cargas de usuarios, descargas, integraciones y copias recibidas de terceros, conviene elegir data. Una opción más permisiva debe ser una decisión técnica documentada, no un atajo.

Crear un filtro personalizado

Una aplicación puede necesitar reglas más estrictas. Por ejemplo, aceptar únicamente CSV, JSON y TXT, rechazar enlaces y archivos especiales, limitar el tamaño y normalizar permisos.

from pathlib import Path
import tarfile

EXTENSIONES = {".csv", ".json", ".txt"}
MAX_ARCHIVO = 20 * 1024 * 1024

def filtro_importacion(member, path):
    nombre = Path(member.name)

    if member.isdir():
        return member

    if not member.isfile():
        return None

    if nombre.suffix.lower() not in EXTENSIONES:
        return None

    if member.size > MAX_ARCHIVO:
        return None

    return member.replace(mode=0o600)

with tarfile.open("entrada.tar") as tar:
    tar.extractall("temporal", filter=filtro_importacion)

Devolver None omite un miembro. Devolver el miembro lo acepta, opcionalmente con metadatos modificados. De esta forma, la política queda centralizada y es más fácil de revisar.

Rechazar enlaces innecesarios

Los enlaces simbólicos y los enlaces duros son útiles en archivos de sistema, pero la mayoría de las importaciones de datos no los necesita. Rechazarlos elimina una clase importante de redirecciones de ruta.

def sin_enlaces(member, path):
    if member.issym() or member.islnk():
        return None
    return tarfile.data_filter(member, path)

La función reutiliza la protección del filtro estándar y añade una regla específica del proyecto. Es preferible componer reglas que reimplementar toda la lógica desde cero.

Limitar cantidad y tamaño total

Un archivo puede agotar recursos aunque cada elemento sea pequeño. Puede incluir cientos de miles de entradas o declarar un tamaño descomprimido enorme. Comprueba la cantidad de miembros y la suma total antes de extraer.

MAX_MIEMBROS = 5000
MAX_TOTAL = 500 * 1024 * 1024

with tarfile.open("entrada.tar") as tar:
    miembros = tar.getmembers()

    if len(miembros) > MAX_MIEMBROS:
        raise ValueError("Demasiados miembros")

    total = sum(m.size for m in miembros if m.isfile())
    if total > MAX_TOTAL:
        raise ValueError("Tamaño total excedido")

    tar.extractall("temporal", members=miembros, filter="data")

Los límites deben adaptarse al espacio disponible, al volumen esperado y a los tiempos máximos de la aplicación.

Extraer en una zona temporal

No extraigas un TAR no confiable directamente en una carpeta activa. Crea un directorio nuevo, realiza la extracción, valida los resultados y mueve solamente los archivos aprobados al destino final.

Este diseño también facilita la limpieza. Si algo falla, se elimina todo el árbol temporal. Los datos activos permanecen intactos y el usuario no observa un resultado parcial.

Validar el contenido después

La validación del archivo es solo la primera capa. Un fichero con extensión .json puede contener datos inválidos. Analiza los formatos estructurados, valida esquemas, controla filas, codificación y campos obligatorios.

En el caso de plantillas, configuraciones o formatos ejecutables, aplica revisiones adicionales. La extensión del nombre no equivale a una validación real del contenido.

Errores y limpieza

No ignores las excepciones. Registra el identificador de la operación, el origen del TAR, el miembro rechazado y la razón de la política. Evita mostrar rutas internas o detalles sensibles al usuario final.

import tarfile

try:
    with tarfile.open("entrada.tar") as tar:
        tar.extractall("temporal", filter="data")
except tarfile.TarError as error:
    raise RuntimeError("Archivo TAR inválido o inseguro") from error

Elimina siempre el directorio temporal cuando la operación no termina correctamente. En servicios continuos, los residuos pueden ocupar disco y complicar el diagnóstico.

Privilegios mínimos

El proceso de extracción debe ejecutarse con un usuario que no pueda modificar el sistema, el código de la aplicación, secretos ni datos de otros clientes. Los permisos del sistema de archivos son una segunda barrera importante.

Para cargas especialmente riesgosas, usa un contenedor, sandbox, proceso desechable o worker con límites de CPU, memoria, disco y tiempo.

Compatibilidad entre versiones

Si una biblioteca admite varias versiones de Python, comprueba la disponibilidad y el comportamiento del parámetro filter. No hagas una degradación silenciosa hacia una extracción insegura. Cuando esta protección sea un requisito, establece una versión mínima del intérprete.

Pruebas recomendadas

Crea archivos de prueba con rutas normales, segmentos .., rutas absolutas, enlaces simbólicos, enlaces duros, archivos grandes, demasiados miembros, extensiones prohibidas, permisos extraños y cabeceras dañadas. Verifica que las entradas inseguras se rechacen y que el destino final permanezca sin cambios.

También prueba archivos válidos generados por cada sistema compatible. Una política segura debe ser estricta, pero predecible y bien documentada.

Observabilidad

Registra miembros aceptados y rechazados, tamaño declarado, duración, errores de limpieza y nombre de la política. Estas métricas ayudan a detectar abuso, integraciones rotas o cambios inesperados en el productor del archivo.

Lecturas relacionadas

Consulta también zipfile.Path en Python, os.path.splitroot en Python, pathlib.Path.info en Python y sqlite3 autocommit en Python. Para detalles oficiales, revisa la documentación de tarfile y la documentación de pathlib.

Conclusión

tarfile extraction_filter convierte la extracción en una operación gobernada por una política. Para archivos externos, empieza con filter="data", rechaza enlaces y tipos innecesarios, impone límites, utiliza una carpeta temporal, valida el contenido y ejecuta el proceso con privilegios mínimos. Estas capas crean un flujo TAR mucho más seguro y mantenible en Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código Python mostrando avisos controlados con catch_warnings
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    catch_warnings: captura warnings en pruebas Python

    Aprende catch_warnings en Python para capturar, probar y controlar avisos con filtros específicos y alcance seguro.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código Python que representa referencias persistentes de pickle
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    pickle persistent_id: serializa referencias externas

    Aprende pickle persistent_id en Python para referencias externas estables, validación, seguridad, rendimiento y compatibilidad.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código binario que representa buffers y vistas de memoria en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    memoryview.count: cuenta valores sin copiar buffers

    Aprende memoryview.count en Python para contar bytes y valores en buffers sin copias, con formatos, límites y buenas prácticas.

    Ler mais

    Tempo de leitura: 6 minutos
    06/10/2026
    Código Python y anotaciones de tipos
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    annotationlib: evita imports circulares en anotaciones

    Aprende annotationlib en Python para inspeccionar anotaciones diferidas, evitar imports circulares y crear herramientas seguras.

    Ler mais

    Tempo de leitura: 6 minutos
    06/10/2026
    Código Python en pantalla que representa inspección de módulos y paquetes
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    inspect.ispackage: identifica paquetes Python

    Aprende inspect.ispackage en Python para identificar paquetes, explorar módulos y crear herramientas de introspección seguras.

    Ler mais

    Tempo de leitura: 5 minutos
    05/10/2026
    Portátil con código y gráficos de rendimiento para analizar sys._jit en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sys._jit: detecta y mide el JIT experimental

    Aprende sys._jit en Python para detectar soporte JIT experimental, medir rendimiento y evitar decisiones frágiles.

    Ler mais

    Tempo de leitura: 5 minutos
    05/10/2026