
CVE-2026-9335: KerasFileEditor y load_weights siguen los ExternalLinks de h5py, divulgando el contenido arbitrario de archivos HDF5 locales en keras ≤ 3.14.0. Aviso + PoCs verificados.
ExternalLink en KerasDos APIs públicas de Keras — keras.saving.KerasFileEditor y
keras.saving.load_weights / — leen miembros de grupos HDF5 mediante
sin verificar el tipo de enlace. h5py
/ al indexar, por lo que un archivo ,
o proporcionado por un atacante que contenga solo un enlace hace que Keras lea el contenido
de .
model.load_weightsExternalLinkSoftLink.weights.h5.h5.kerasKeras ya incluye la protección correcta (
safe_get_h5_group/safe_get_h5_datasetensaving_lib.py) — estos dos puntos de entrada simplemente no la invocan.
| CVE | CVE-2026-9335 |
| Afectado | keras-team/keras ≤ 3.14.0 (PyPI) |
| Tipo | Path Traversal / Exposición de información (CWE-22, CWE-200) |
| CVSS 3.1 | AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N → 6.5 (Medio) |
| Impacto | Divulgación de cualquier archivo HDF5 local que la víctima pueda leer |
| Vector | La víctima abre/carga un archivo malicioso .weights.h5 / .h5 / .keras |
| Estado | Corregido en keras 3.15.0 (PR #22899 / #22900); validado en huntr (2026-05-22, mantenedor hertschuh) |
| Reportero | Jonathan Paparo (jonathan-paparo) |
| Ruta | Qué es |
|---|---|
advisory/CVE-2026-9335.md | Informe técnico completo: causa raíz, ambos puntos, salida del PoC, corrección |
poc/poc_file_editor.py | PoC 1 — KerasFileEditor sigue un ExternalLink y filtra un h5 de la víctima |
poc/poc_load_weights.py | PoC 2 — model.load_weights extrae los pesos de una víctima mediante ExternalLink |
poc/requirements.txt | Entorno de reproducción fijado |
docs/timeline.md | Cronología de divulgación coordinada |
# keras/src/saving/saving_api.py (load_weights, rama heredada .h5)
with h5py.File(filepath, "r") as f:
if "layer_names" not in f.attrs and "model_weights" in f:
f = f["model_weights"] # <-- Un ExternalLink aquí es desreferenciado automáticamente por h5py
f["model_weights"] (y el recorrido análogo data[key] en file_editor.py)
sigue de forma transparente un enlace hacia otro archivo. El patrón seguro que Keras usa
en otros lugares verifica primero el tipo de enlace:
# keras/src/saving/saving_lib.py (safe_get_h5_group)
group_type = parent.get(name, default=None, getclass=True, getlink=True)
if group_type in (h5py.ExternalLink, h5py.SoftLink):
raise ValueError(f"Not allowed: H5 file with {group_type.__name__}")
python -m pip install -r poc/requirements.txt
# PoC 1 — KerasFileEditor filtra el contenido de un archivo h5 separado de la víctima
KERAS_BACKEND=jax python poc/poc_file_editor.py
# PoC 2 — model.load_weights carga los pesos de un archivo de la víctima mediante un ExternalLink
KERAS_BACKEND=jax python poc/poc_load_weights.py
Cada PoC crea sus propios archivos h5 desechables de "víctima" y "atacante" en el
directorio temporal del sistema, demuestra la fuga, imprime
*** VULNERABILITY CONFIRMED *** y se limpia a sí mismo. Verificado en
keras==3.14.0, Python 3.12.6, backend JAX.
Enruta ambos puntos a través del helper existente safe_get_h5_group, o añade una
verificación previa data.get(key, default=None, getclass=True, getlink=True) que rechace
(h5py.ExternalLink, h5py.SoftLink) antes de indexar. Consulta el
advisory para ver los diffs exactos.
Este material se publica con fines defensivos y educativos después de la divulgación coordinada y la asignación del CVE. Los PoC operan únicamente sobre archivos que ellos mismos crean en un directorio temporal. No utilices estas técnicas contra sistemas o datos que no estés autorizado a probar.
Descubierto y reportado por Jonathan Paparo (huntr:
jonathan-paparo). Validado por el
mantenedor de keras-team hertschuh.