sistema: OPERATIVO
← volver a todos los hacks
SUPPLY CHAIN CRITICAL NEW

Inyección por config de Transformers: una RCE silenciosa que esquiva trust_remote_code

CVE-2026-4372, divulgada el 4 de junio de 2026, permite que un único campo de config.json ejecute código del atacante en una simple llamada from_pretrained() — esquivando trust_remote_code=False en Hugging Face Transformers.

2026-06-10 // 8 min affects: huggingface-transformers, kernels

¿Qué es esto?

CVE-2026-4372 es una vulnerabilidad de ejecución remota de código (RCE) en la biblioteca transformers de Hugging Face, divulgada públicamente el 4 de junio de 2026 por Yotam Perkal (Pluto Security) y reportada ese mismo día por CSO Online. Permite ejecutar código Python arbitrario en quien cargue un modelo manipulado mediante la simple llamada from_pretrained()sin que la víctima haya establecido nunca trust_remote_code=True.

El detonante es un único campo en el config.json del modelo. No hay advertencias, ni solicitud de consentimiento, ni registros inusuales: el código se ejecuta dentro de la biblioteca antes incluso de que from_pretrained() retorne. El NVD publicó la CVE el 24 de mayo de 2026 con una puntuación CVSS 3.0 de 7,8 (alta), clasificada como CWE-1066. La entrada de Pluto señala que la enviaron inicialmente como crítica; Hugging Face rebajó la puntuación porque la explotación depende de la presencia de un paquete opcional.

Cómo funciona

El fallo nace de la intersección de tres decisiones de diseño independientes, ninguna peligrosa por sí sola. Pluto trazó toda la cadena; CSO Online la corroboró con el parche de los mantenedores.

Primero, cuando transformers analiza un config.json descargado, un bucle genérico en configuration_utils.py aplica cada par clave-valor sobre el objeto de configuración mediante setattr, sin lista de permitidos ni distinción entre parámetros públicos y atributos internos con prefijo de guion bajo:

# configuration_utils.py — de JSON no confiable a atributos de objeto
for key, value in kwargs.items():
    setattr(self, key, value)   # sin allowlist, sin validación

Segundo, uno de esos atributos internos — _attn_implementation_internal — controla qué núcleo de atención usa el modelo. Desde transformers v4.50.0 (función «Hub Kernels»), un valor con forma owner/repo se trata como referencia a un paquete de núcleo descargable desde el Hub. La ruta de despacho en hub_kernels.py acepta cualquier cadena owner/repo y la importa:

# hub_kernels.py (simplificado) — cualquier cadena owner/repo se descarga e importa
def is_kernel(attn_implementation):
    return re.search(r"^[^/:]+/[^/:]+...$", attn_implementation) is not None
# -> get_kernel() -> descarga el paquete del Hub -> import vía importlib

Tercero, esa importación es sin sandbox: sin firma de código, sin verificación de integridad, sin aviso. Importar un paquete Python ejecuta su __init__.py. Así, el atacante publica un modelo de aspecto normal cuyo config.json incluye una línea extra:

{
  "model_type": "llama",
  "architectures": ["LlamaForCausalLM"],
  "_attn_implementation_internal": "attacker-acct/optimized-attn-kernel"
}

Cuando la víctima ejecuta AutoModelForCausalLM.from_pretrained("attacker-acct/finance-llama-7b"), la biblioteca descarga e importa el paquete del atacante, ejecutando lo que haya en su __init__.py con los privilegios del usuario. Funciones ficticias en ese paquete permiten que la carga termine con normalidad: nada parece anómalo.

Lo esencial: el valor por defecto trust_remote_code=False nunca entra en juego — los propios saneadores de la biblioteca cubrían el campo público attn_implementation y eliminaban _attn_implementation_internal en la ruta de escritura, pero nunca lo filtraban en la ruta de lectura desde el JSON no confiable. La puerta principal estaba cerrada; la trasera, abierta de par en par.

Por qué importa

transformers es uno de los paquetes Python más instalados del mundo: según Pluto, más de 2.200 millones de instalaciones PyPI acumuladas y unos 146 millones de descargas mensuales. La ruta vulnerable se introdujo en v4.56.0 (29 de agosto de 2025) y se eliminó en v5.3.0 (4 de marzo de 2026) — una ventana de exposición de unos 187 días durante la cual Pluto midió ~232 millones de descargas de versiones vulnerables (4.56.0–5.2.x).

La explotación requiere el paquete opcional kernels — un factor limitante real, pero engañoso. kernels viene con transformers[all], con los Dockerfiles de referencia de Hugging Face y con la mayoría de configuraciones de inferencia acelerada por GPU. Como dice Pluto, quienes lo tienen instalado son justamente los objetivos de alto valor: plataformas de ML empresariales, pipelines de CI/CD que llaman from_pretrained() automáticamente y clústeres GPU que guardan credenciales en la nube, datos de entrenamiento y artefactos de modelos. Una sola carga de modelo comprometida puede entregar claves AWS, claves SSH, secretos .env y configuraciones de Kubernetes, y habilitar el movimiento lateral.

No es teórico. CSO Online recuerda que un repositorio malicioso que se hacía pasar por un modelo «Privacy Filter» de OpenAI alcanzó el primer puesto en tendencias del Hub y 244.000 descargas en 18 horas antes de ser retirado — y ese ataque aún exigía que la víctima ejecutara manualmente un script. CVE-2026-4372 elimina incluso ese paso. Recuerda a CVE-2025-32434 (abril de 2025), el fallo de torch.load (PyTorch) que lograba RCE pese a weights_only=True — la misma forma de bug: un modo «seguro» documentado que deja escapar una primitiva de ejecución de código por una ruta adyacente que la bandera no cubría.

Una segunda lección trata de la visibilidad, no de la rapidez del parche. Hugging Face corrigió rápido (10 días desde el reporte hasta la v5.3.0), pero el arreglo llegó como una línea de «vulnerabilidad de seguridad» en unas notas de versión rutinarias; la CVE no aterrizó en el NVD hasta 81 días después. Según la telemetría de Pluto, las versiones vulnerables aún se descargaban de 7 a 8 millones de veces por semana — alrededor de un cuarto de las instalaciones semanales — meses después del parche. Un parche sin un aviso audible no protege a los defensores que nunca supieron que debían aplicarlo.

Defensas

Si usa transformers, actualice a la v5.3.0 o posterior ya, y compruebe si algún entorno fijado sigue en 4.56.0–5.2.x. Pluto y CSO confirman que las versiones vulnerables siguen descargándose mucho.

Audite sus configuraciones. Busque _attn_implementation_internal (y, tras el parche, _experts_implementation_internal) en cualquier config.json en caché o descargado. Su presencia en una config procedente del Hub es una señal de alerta. En general, rechace antes de cargar las configs con campos inesperados con prefijo de guion bajo.

Trate la carga de modelos como una superficie de ejecución de código, sean cuales sean las banderas «seguras». Esta es la lección duradera. Ejecute from_pretrained() (y torch.load()) dentro de contenedores aislados y monitorizados, sin credenciales del host, sin acceso de red saliente y con permisos de disco mínimos. No deje que un proceso que carga modelos no confiables guarde también secretos de producción.

Verifique la procedencia. Prefiera modelos de editores conocidos; para los desconocidos, herramientas como el Model Provenance Kit de código abierto de Cisco pueden tomar huellas de pesos, tokenizadores y metadatos de arquitectura frente a familias de modelos base conocidas.

El propio parche v5.3.0 es defensa en profundidad: pone _attn_implementation_internal y _experts_implementation_internal en lista de bloqueo dentro del bucle setattr (PR #44395), y ahora exige trust_remote_code=True para cualquier repositorio de núcleo fuera de la organización oficial kernels-community. Como señala Pluto, una lista de bloqueo solo vale lo que la previsión del desarrollador — una lista de permitidos de los campos de config sería el diseño robusto a largo plazo.

Estado

ElementoDetalle
CVECVE-2026-4372 (CWE-1066), CVSS 3.0 base 7,8 (alta, NVD)
Afectadotransformers 4.56.0 – 5.2.x con el paquete opcional kernels
Introducidov4.56.0, 2025-08-29 (refactor del despacho Hub Kernels)
Corregidov5.3.0, 2026-03-04 (PR #44395)
Reportado / Divulgadoinforme huntr 2026-02-23; publicación NVD 2026-05-24; análisis público 2026-06-04
DescubridorYotam Perkal, Pluto Security
AcciónActualizar a ≥ 5.3.0; auditar configs; aislar la carga de modelos

Sources