CVE-2025-10157: omisión del escaneo de picklescan que conduce a la ejecución arbitraria de código

picklescan es una popular biblioteca de código abierto para Python diseñada para detectar y prevenir vulnerabilidades relacionadas con la deserialización insegura en el formato pickle de Python. Se utiliza ampliamente en tuberías (pipelines) de Machine Learning (ML) e Inteligencia Artificial (IA) para analizar modelos preentrenados en busca de código malicioso antes de que sean cargados, desempeñando un papel fundamental como control de seguridad en el ciclo de vida MLOps. Cualquier aplicación que maneje datos serializados provenientes de fuentes no confiables puede depender de esta herramienta para protegerse.

El impacto de esta vulnerabilidad es crítico. Representa una omisión completa del mecanismo de seguridad del escáner, lo que lo vuelve ineficaz. Un atacante puede crear un archivo malicioso que la herramienta certifique erróneamente como “seguro” y que, una vez cargado por una aplicación, conduzca a una ejecución remota de código no autenticada.

Existe código de explotación público para esta vulnerabilidad y, dada su naturaleza de elusión de un control de seguridad, es altamente probable su explotación activa. Cualquier organización que utilice versiones vulnerables de picklescan para desinfectar archivos no confiables, en particular aquellas que incorporan modelos de ML de terceros, está en riesgo inmediato de compromiso del sistema.

Productopicklescan
Fecha2025-12-05 12:14:05

Resumen técnico

La vulnerabilidad se debe a un control inadecuado de los módulos y funciones peligrosas dentro de la lógica de validación unsafe_globals. La causa principal es una CWE-183: Expresión regular permisiva (o un defecto lógico similar), en la que el escáner realiza una comparación de cadenas exacta contra una lista de bloqueo que contiene módulos peligrosos conocidos (ej. “asyncio”, “subprocess”), pero no verifica recursivamente los submódulos de esos paquetes.

La cadena de ataque es la siguiente:

  1. Un atacante crea un archivo pickle malicioso que contiene una carga útil (payload) que invoca una función peligrosa desde un submódulo de un paquete bloqueado (ej. asyncio.unix_events en lugar del paquete padre asyncio).
  2. La versión vulnerable de picklescan analiza el archivo. Su escáner compara el módulo “asyncio.unix_events” con su lista de bloqueo interna.
  3. Dado que la lista de bloqueo contiene solo la entrada exacta “asyncio”, el control no detecta una coincidencia y picklescan señala erróneamente el archivo malicioso como seguro.
  4. Una aplicación, confiando en la salida del escáner, carga el archivo pickle mediante pickle.load().
  5. El deserializador de Python ejecuta la carga útil incorporada, otorgando al atacante la ejecución arbitraria de código con los permisos del proceso de la aplicación.

Versiones afectadas:

  • Las versiones de picklescan 0.0.30 y anteriores son vulnerables.

Un ejemplo conceptual de la lógica errónea:

# Lógica vulnerable (Conceptual)
def is_dangerous(module_name):
    blocklist = {"os", "subprocess", "asyncio"}
    return module_name in blocklist # Falla para "os.path"

# Lógica corregida (Conceptual)
def is_dangerous_fixed(module_name):
    blocklist = {"os", "subprocess", "asyncio"}
    # Verifica si el módulo o cualquiera de sus paquetes padres están en la lista de bloqueo
    parts = module_name.split('.')
    for i in range(len(parts)):
        sub_module = ".".join(parts[:i+1])
        if sub_module in blocklist:
            return True
    return False

Este bypass socava completamente la garantía de seguridad ofrecida por la biblioteca, permitiendo a un atacante experto comprometer totalmente el sistema.

Recomendaciones

  • Aplicar el parche inmediatamente: actualizar la biblioteca picklescan a una versión posterior a la 0.0.30. Todas las versiones anteriores se consideran vulnerables.
  • Mitigaciones: si no es posible aplicar el parche inmediatamente, trate todos los archivos escaneados por versiones vulnerables de picklescan como no confiables. La mitigación más efectiva es deshabilitar la carga automática de archivos pickle o modelos de ML provenientes de fuentes no verificadas o no confiables.
  • Hunting y monitoreo:
    • Volver a escanear todos los archivos pickle y modelos de ML existentes en el entorno con una versión corregida del escáner.
    • Monitorear los registros (logs) de las aplicaciones en busca de comportamientos anómalos, errores durante la deserialización o la creación inesperada de procesos hijos (ej. shell, reverse shell) por parte de aplicaciones de Python que manejan archivos pickle.
    • Analizar el tráfico de red en busca de conexiones salientes inesperadas desde servidores que sirven modelos de ML o procesan datos.

  • Respuesta a incidentes: en caso de sospecha de compromiso, aísle inmediatamente el host afectado de la red para prevenir movimientos laterales. Conserve el archivo malicioso y los registros del sistema para un análisis forense. Inicie un protocolo de rotación de credenciales para todos los servicios que se ejecutan en la máquina comprometida o que son accesibles desde ella.
  • Defensa en profundidad: nunca deserialice datos provenientes de fuentes no confiables. Ejecute las aplicaciones que procesan datos externos, como las API para la carga de modelos de ML, en entornos sandbox o contenerizados con privilegios mínimos y filtros estrictos sobre el tráfico saliente.

[Callforaction-THREAT-Footer]