
Asignación de recursos sin límites ni limitación de velocidad en el componente de carga de pesos HDF5 en Google Keras 3.0.0 hasta 3.13.0 en todas las plataformas permite a un atacante remoto causar una Denegación de Servicio (DoS) mediante el agotamiento de la memoria y un bloqueo del intérprete de Python a través de un archivo .keras manipulado.
| Campo | Detalles |
|---|---|
| ID CVE | CVE-2026-0897 |
| Paquete | keras (Google Keras) |
| Registro | PyPI |
| Versiones Afectadas | 3.0.0 hasta 3.13.0 (inclusive) |
| Tipo de Vulnerabilidad | CWE-770: Asignación de Recursos sin Límites o Aceleración |
| Puntuación CVSS | 7.1 Alta (CVSS 4.0, CNA: Google Inc.) |
| Vector CVSS | CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N |
| Vector de Ataque | Red |
| Complejidad del Ataque | Baja |
| Privilegios Requeridos | Ninguno |
| Interacción del Usuario | Pasiva (la víctima carga un archivo de modelo) |
| Impacto en Disponibilidad | Alto |
| Impacto en Confidencialidad | Ninguno |
| Impacto en Integridad | Ninguno |
| Publicado en NVD | 15 de enero de 2026 |
| Última Modificación en NVD | 23 de enero de 2026 |
| Fuente / CNA | Google Inc. |
| Reportado Por | HyperPS (Sarvesh Patil) vía huntr.dev / GHSA |
| Estado de la Corrección | Fusionado — PR #21880 |
Existe una vulnerabilidad de Denegación de Servicio en el componente de carga de pesos HDF5 de Google Keras versiones 3.0.0 hasta 3.13.0 en todas las plataformas. La vulnerabilidad se debe a la ausencia de cualquier validación o limitación al procesar los metadatos de forma de conjuntos de datos HDF5 declarados dentro de un archivo .keras.
El formato HDF5 permite que los conjuntos de datos declaren su forma (dimensiones del tensor) como metadatos. Cuando Keras carga los pesos del modelo desde un archivo .keras, lee esta forma declarada e intenta asignar un bloque de memoria correspondiente antes de que se transfiera cualquier dato. Debido a que Keras no realiza ninguna verificación de límites sobre la forma declarada antes de la asignación, un atacante puede crear un archivo model.weights.h5 que declare una forma astronómicamente grande — por ejemplo (1000000, 1000000, 1000000) — lo que provoca que Keras intente una asignación de memoria a escala de petabytes. Esto agota toda la memoria disponible del sistema y bloquea el intérprete de Python.
No se requiere inferencia ni interacción adicional después de cargar el modelo. El ataque se activa completamente en el momento de la carga.
| Archivo | Descripción |
|---|---|
keras/src/saving/file_editor.py | KerasFileEditor._extract_weights_from_store() — lee la forma del conjunto de datos HDF5 y asigna memoria sin validación de tamaño ni limitación |
La vulnerabilidad se ubica específicamente en la clase KerasFileEditor, responsable de deserializar los tensores de pesos del modelo desde los almacenes HDF5 incrustados dentro de los archivos .keras.
| Métrica | Valor | Significado |
|---|---|---|
| Vector de Ataque (AV) | Red | Explotable remotamente mediante un archivo de modelo distribuido |
| Complejidad del Ataque (AC) | Baja | No se requieren condiciones especiales ni condiciones de carrera |
| Requisitos del Ataque (AT) | Ninguno | No se necesita configuración de despliegue previa |
| Privilegios Requeridos (PR) | Ninguno | No se requiere autenticación ni cuenta |
| Interacción del Usuario (UI) | Pasiva | La víctima debe cargar el archivo .keras malicioso |
| Disponibilidad del Sistema Vulnerable (VA) | Alta | El intérprete de Python se bloquea; el servicio queda completamente no disponible |
| Confidencialidad del Sistema Vulnerable (VC) | Ninguna | No hay divulgación de datos |
| Integridad del Sistema Vulnerable (VI) | Ninguna | No hay modificación de datos |
| Impacto en Sistemas Posteriores (SC/SI/SA) | Ninguno | El impacto se limita al proceso de carga |
.keras de fuentes no confiables o proporcionadas por el usuario es vulnerable| Contexto | Riesgo |
|---|---|
APIs públicas de servidores de modelos que aceptan archivos .keras subidos por el usuario | El atacante bloquea el servicio de inferencia con una sola solicitud |
| Plataformas de ML que alojan descargas de modelos de la comunidad (p. ej., Hugging Face) | Un modelo envenenado causa DoS a cualquier investigador que lo descargue y cargue |
| Entornos de aprendizaje federado | Un participante malicioso distribuye un archivo de pesos manipulado para bloquear el coordinador o los nodos pares |
| Pipelines de CI/CD que cargan checkpoints de modelos | Un checkpoint comprometido o sustituido causa fallo del pipeline e indisponibilidad |
| Servicios de chatbots o NLP que recargan modelos en caliente en tiempo de ejecución | Una sola solicitud de recarga maliciosa derriba el servicio |
El formato de archivo HDF5 almacena los metadatos de los tensores — incluidas las declaraciones de forma — por separado de los bytes de datos reales. Cuando KerasFileEditor._extract_weights_from_store() encuentra una entrada de conjunto de datos, lee la forma declarada y llama a NumPy para pre-asignar un array de las dimensiones correspondientes antes de leer cualquier dato del disco.
Debido a que la forma son metadatos, un archivo HDF5 mínimo puede declarar una forma que requeriría petabytes de memoria mientras el archivo en sí permanece con solo unos pocos kilobytes de tamaño. La proporción entre el tamaño del archivo y el tamaño de la asignación convierte esto en un ataque de amplificación altamente efectivo.
Una forma como (1000000, 1000000, 1000000) con un dtype de float de 32 bits solicitaría aproximadamente 4,000 petabytes de memoria. El killer de falta de memoria del SO o el asignador de Python bloquearán el proceso casi instantáneamente.
# keras/src/saving/file_editor.py (pre-fix, simplified)
def _extract_weights_from_store(self, h5_file, inner_path=""):
for key in h5_file.keys():
obj = h5_file[key]
if isinstance(obj, h5py.Dataset):
# Shape is read from metadata — no validation performed
shape = obj.shape
# NumPy attempts to allocate based on declared shape
data = np.zeros(shape, dtype=obj.dtype) # VULNERABLE: unbounded allocation
La ausencia de cualquier verificación sobre shape antes de llamar a np.zeros() es la causa raíz.
Esta información se proporciona únicamente con fines educativos y defensivos. No pruebe contra sistemas que no le pertenezcan o para los cuales no tenga autorización explícita de pruebas.
.keras Malicioso