
CVE-2026-9335: KerasFileEditor и load_weights следуют за ExternalLinks из h5py, раскрывая содержимое произвольных локальных HDF5-файлов в keras ≤ 3.14.0. Рекомендации + проверенные PoC.
ExternalLink в KerasДва публичных API Keras — keras.saving.KerasFileEditor и
keras.saving.load_weights / — читают элементы групп HDF5 с помощью
без проверки типа ссылки. h5py
/ при индексации, поэтому предоставленный атакующим файл ,
или , содержащий только ссылку, заставляет Keras читать содержимое
.
model.load_weightsExternalLinkSoftLink.weights.h5.h5.kerasВ Keras уже есть корректная защита (
safe_get_h5_group/safe_get_h5_datasetвsaving_lib.py) — эти две точки входа просто не вызывают её.
| CVE | CVE-2026-9335 |
| Затронутые версии | keras-team/keras ≤ 3.14.0 (PyPI) |
| Тип | Path Traversal / Раскрытие информации (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 (Medium) |
| Воздействие | Раскрытие любого локального файла HDF5, который жертва может прочитать |
| Вектор атаки | Жертва открывает/загружает вредоносный файл .weights.h5 / .h5 / .keras |
| Статус | Исправлено в keras 3.15.0 (PR #22899 / #22900); подтверждено на huntr (2026-05-22, мейнтейнер hertschuh) |
| Автор отчёта | Jonathan Paparo (jonathan-paparo) |
| Путь | Что это |
|---|---|
advisory/CVE-2026-9335.md | Полное техническое описание: первопричина, обе точки входа, вывод PoC, исправление |
poc/poc_file_editor.py | PoC 1 — KerasFileEditor следует по ExternalLink и раскрывает h5 жертвы |
poc/poc_load_weights.py | PoC 2 — model.load_weights загружает веса жертвы через ExternalLink |
poc/requirements.txt | Зафиксированная среда воспроизведения |
docs/timeline.md | Хронология скоординированного раскрытия |
# keras/src/saving/saving_api.py (load_weights, ветка legacy .h5)
with h5py.File(filepath, "r") as f:
if "layer_names" not in f.attrs and "model_weights" in f:
f = f["model_weights"] # <-- ExternalLink здесь автоматически разыменовывается h5py
f["model_weights"] (и аналогичный обход data[key] в file_editor.py)
прозрачно следует по ссылке в другой файл. Безопасный шаблон, который Keras использует
в других местах, сначала проверяет тип ссылки:
# 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 раскрывает содержимое отдельного файла h5 жертвы
KERAS_BACKEND=jax python poc/poc_file_editor.py
# PoC 2 — model.load_weights загружает веса файла жертвы через ExternalLink
KERAS_BACKEND=jax python poc/poc_load_weights.py
Каждый PoC создаёт собственные одноразовые файлы h5 «жертвы» и «атакующего» в системной
временной директории, демонстрирует утечку, выводит
*** VULNERABILITY CONFIRMED *** и самостоятельно очищает за собой. Проверено на
keras==3.14.0, Python 3.12.6, бэкенд JAX.
Направьте обе точки входа через существующий хелпер safe_get_h5_group или добавьте
предварительную проверку data.get(key, default=None, getclass=True, getlink=True), которая отклоняет
(h5py.ExternalLink, h5py.SoftLink) перед индексацией. См.
advisory для точных диффов.
Этот материал публикуется в защитных и образовательных целях после скоординированного раскрытия и присвоения CVE. PoC работают только с файлами, которые они сами создают во временной директории. Не используйте эти техники против систем или данных, которые вы не уполномочены тестировать.
Обнаружено и сообщено Jonathan Paparo (huntr:
jonathan-paparo). Подтверждено
мейнтейнером keras-team hertschuh.