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
- Vulnerable code — saving_lib.py
- h5py ExternalLink documentation
- PoC — malicious.keras and reproduction script
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
@lemonkiil
UNPROVEN
Fixed by
@hertschuh
UNPROVEN