model.weights.h5: h5py.ExternalLink at Group level silently followed during load_model(), bypassing CVE-2025-9905 fix — information disclosure from arbitrary HDF5 files in keras-team/keras

Valid

Reported on Mar 12th 2026


Keras 3.x introduced a fix for CVE-2025-9905 by checking dataset.external in H5IOStore._verify_dataset(). This check blocks datasets whose raw bytes are stored in external files via the HDF5 "External Data Storage" mechanism.

However, HDF5 supports a second, unrelated external-reference mechanism: h5py.ExternalLink, a named link that transparently redirects an entire Group to an arbitrary path in an external HDF5 file. This link type is never checked in the Keras loading path. When an attacker places an ExternalLink at the layer-group level inside a crafted model.weights.h5, Keras follows the link silently and loads weight tensors from the external file — without raising an exception or warning, even with safe_mode=True.

Impact

An attacker publishes a malicious model whose model.weights.h5 contains an ExternalLink pointing to a known HDF5 file on the victim's system. When the victim calls keras.saving.load_model(), the target file is read silently and its contents are loaded into the model's weight tensors. No exception is raised. safe_mode=True provides no protection.

Confirmed on keras 3.13.2, h5py 3.16.0, Python 3.14.3. Both attack vectors confirmed:

  • Vector A: model.load_weights('.weights.h5') → kernel=99.0, bias=99.0
  • Vector B: keras.saving.load_model(directory, safe_mode=True) → kernel=99.0, bias=99.0

Occurrences


saving_lib.py L1044-L1061](https://github.com/keras-team/keras/blob/340b11033980f6034871f648867c02ce50f35841/keras/src/saving/saving_lib.py#L1044-L1061)

_verify_group() and _verify_dataset() — ExternalLink not checked in either validation method

References

CVE

CVE-2026-9337 assigned

Vulnerability Type

CWE-200: Exposure of Sensitive Information to an Unauthorized Actor

Severity

Medium (6.5)

Attack vector Network

Attack complexity Low

Privileges required None

User interaction Required

Scope Unchanged

Confidentiality High

Integrity None

Availability None

Open in visual CVSS calculator

Registry

Pypi

Affected Version

3.13.2

Visibility

Public

Status

Fixed

Disclosure Bounty

$125

Fix Bounty

$31.25

Found by

Lilith

@lemonkiil

UNPROVEN

Fixed by

hertschuh

@hertschuh

UNPROVEN