Picklescan es una biblioteca de seguridad diseñada para analizar archivos pickle de Python en busca de contenido malicioso. Los archivos pickle son un método común para serializar y deserializar estructuras de objetos de Python, utilizado extensivamente en tuberías (pipelines) de Machine Learning (ML) para guardar y cargar modelos entrenados (por ejemplo, modelos de PyTorch). Debido al riesgo intrínseco de ejecución arbitraria de código durante la deserialización, se emplean herramientas como picklescan para garantizar que solo se procesen archivos pickle “seguros”.
Esta vulnerabilidad representa una omisión fundamental de la promesa central de seguridad de la herramienta, creando una falsa sensación de seguridad. Cualquier aplicación de Python, particularmente los sistemas de ML/IA, que dependa de una versión vulnerable de picklescan para sanear archivos no confiables está en alto riesgo. Un atacante puede crear un archivo malicioso que la herramienta aprobará como seguro, lo que llevará a una ejecución remota de código (RCE) cuando el archivo sea utilizado por la aplicación aguas abajo.
La vulnerabilidad se considera de alto riesgo porque subvierte un control de seguridad. Al momento de redactar este informe, no se conocen exploits activos en circulación, y la vulnerabilidad no está listada en el catálogo KEV (Known Exploited Vulnerabilities) de CISA. Sin embargo, existe una prueba de concepto (proof-of-concept) pública, lo que aumenta la probabilidad de una explotación futura.
| Producto | picklescan |
| Fecha | 2025-12-05 00:39:26 |
Resumen técnico
La vulnerabilidad es una omisión del escaneo de seguridad arraigada en un control incompleto de los módulos peligrosos dentro de un archivo pickle. La causa raíz se identifica como CWE-184: Lista negra incompleta. La herramienta picklescan realiza la validación de seguridad verificando si un archivo pickle intenta importar y utilizar módulos presentes en una lista de exclusión de módulos notoriamente peligrosos (por ejemplo, os, subprocess, asyncio). Sin embargo, la verificación utiliza una coincidencia exacta de la cadena del nombre del módulo.
Un atacante puede eludir este control haciendo referencia a un submódulo de un módulo bloqueado. Por ejemplo, si la lista de exclusión contiene asyncio, la herramienta lo bloqueará, pero no bloqueará asyncio.unix_events, que puede utilizarse de igual manera para ejecutar comandos arbitrarios.
La cadena de ataque procede de la siguiente manera:
- Un atacante crea un archivo pickle malicioso que importa un submódulo de un módulo conocido y bloqueado.
- El archivo se envía a una aplicación de Python que utiliza
picklescanpara la validación. picklescananaliza los módulos requeridos por el pickle y los compara con la lista de exclusión.- Dado que el submódulo (por ejemplo,
asyncio.unix_events) no coincide exactamente con ninguna entrada de la lista (por ejemplo,asyncio), el escaneo clasifica erróneamente el archivo como seguro. - La aplicación, confiando en el resultado del escaneo, procede a la deserialización del archivo usando
pickle.load()de Python o una función equivalente. - El proceso de deserialización ejecuta el código especificado en el archivo pickle, provocando una ejecución arbitraria de código con los privilegios de la aplicación de Python.
El defecto conceptual puede ilustrarse de la siguiente manera:
# Lógica conceptualmente vulnerable
# Una lista de exclusión de módulos peligrosos.
DENYLIST = {"os", "subprocess", "asyncio"}
# La verificación falla porque "asyncio.unix_events" no está presente en el conjunto.
def is_module_denied(module_name):
return module_name in DENYLIST
# Lógica conceptual correcta
# La corrección incluye la verificación del módulo base además de la ruta completa.
def is_module_denied_fixed(module_name):
base_module = module_name.split('.')[0]
return base_module in DENYLIST or module_name in DENYLIST
Las versiones específicas vulnerables y las corregidas de picklescan no estaban disponibles al momento de la redacción. Los usuarios deben actualizar a la versión más reciente disponible.
Recomendaciones
- Aplicar el parche inmediatamente: actualizar
picklescana la última versión disponible que incluya la corrección para la omisión mediante submódulos. - Mitigaciones: la defensa principal consiste en no deserializar nunca archivos pickle provenientes de fuentes no confiables, independientemente del escaneo de seguridad. Cuando sea posible, utilice formatos de serialización de datos más seguros como JSON o YAML (con carga segura). Si el uso de pickle es inevitable, asegúrese de que la aplicación que procesa los datos se ejecute con los privilegios mínimos posibles y esté fuertemente aislada.
- Actividades de monitoreo y detección:
- Examinar los registros (logs) de las aplicaciones en busca de errores de deserialización o comportamientos anómalos relacionados con el procesamiento de archivos.
- Monitorear los sistemas que ejecutan aplicaciones de Python en busca de procesos hijos sospechosos. Un proceso de Python que inicia inesperadamente shells (
sh,bash,powershell) o herramientas de red (curl,wget,nc) es un fuerte indicador de compromiso. - Inspeccionar el tráfico de red para detectar conexiones salientes inesperadas desde los servidores de aplicaciones que gestionan la carga de archivos.
- Respuesta a incidentes: si se sospecha de un compromiso, aísle inmediatamente el host involucrado de la red. Conserve los registros de la aplicación, los archivos cargados y una imagen de memoria del proceso en ejecución para análisis forense. Investigue cualquier signo de movimiento lateral o exfiltración de datos originados desde el host comprometido.
- Defensa en profundidad: implemente un filtrado riguroso para el tráfico saliente para bloquear comunicaciones C2 no autorizadas. Utilice soluciones de control de aplicaciones para impedir que el intérprete de Python ejecute código o comandos de sistema no autorizados. Realice copias de seguridad regulares de los datos críticos, incluidos los modelos de ML, en una ubicación segura y fuera de línea (offline).
[Callforaction-THREAT-Footer]