
Allocazione di risorse senza limiti o limitazioni di velocità nel componente di caricamento dei pesi HDF5 in Google Keras 3.0.0 fino alla 3.13.0 su tutte le piattaforme consente a un attaccante remoto di causare una Denial of Service (DoS) tramite l'esaurimento della memoria e il crash dell'interprete Python attraverso un file .keras appositamente predisposto.
| Campo | Dettagli |
|---|---|
| CVE ID | CVE-2026-0897 |
| Pacchetto | keras (Google Keras) |
| Registro | PyPI |
| Versioni interessate | 3.0.0 fino a 3.13.0 (incluse) |
| Tipo di vulnerabilità | CWE-770: Allocazione di risorse senza limiti o throttling |
| Punteggio CVSS | 7.1 Alto (CVSS 4.0, CNA: Google Inc.) |
| Vettore 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 |
| Vettore di attacco | Rete |
| Complessità dell'attacco | Bassa |
| Privilegi richiesti | Nessuno |
| Interazione dell'utente | Passiva (la vittima carica un file di modello) |
| Impatto sulla disponibilità | Alto |
| Impatto sulla riservatezza | Nessuno |
| Impatto sull'integrità | Nessuno |
| Pubblicato su NVD | 15 gennaio 2026 |
| Ultima modifica NVD | 23 gennaio 2026 |
| Fonte / CNA | Google Inc. |
| Segnalato da | HyperPS (Sarvesh Patil) tramite huntr.dev / GHSA |
| Stato della correzione | Integrata — PR #21880 |
Una vulnerabilità di tipo Denial of Service è presente nel componente di caricamento dei pesi HDF5 di Google Keras versioni 3.0.0 fino a 3.13.0 su tutte le piattaforme. La vulnerabilità è causata dall'assenza di qualsiasi validazione o limitazione (throttling) durante l'elaborazione dei metadati di forma (shape) dei dataset HDF5 dichiarati all'interno di un archivio .keras.
Il formato HDF5 consente ai dataset di dichiarare la propria forma (dimensioni dei tensori) come metadati. Quando Keras carica i pesi del modello da un archivio .keras, legge questa forma dichiarata e tenta di allocare un blocco di memoria corrispondente prima che qualsiasi dato venga trasferito. Poiché Keras non esegue alcun controllo dei limiti sulla forma dichiarata prima dell'allocazione, un attaccante può creare un file model.weights.h5 che dichiara una forma astronomicamente grande — ad esempio (1000000, 1000000, 1000000) — inducendo Keras a tentare un'allocazione di memoria su scala petabyte. Questo esaurisce tutta la memoria di sistema disponibile e provoca il crash dell'interprete Python.
Non è richiesta alcuna inferenza né ulteriore interazione dopo il caricamento del modello. L'attacco viene completamente innescato al momento del caricamento.
| File | Descrizione |
|---|---|
keras/src/saving/file_editor.py | KerasFileEditor._extract_weights_from_store() — legge la forma dei dataset HDF5 e alloca memoria senza validazione delle dimensioni o limitazioni (throttling) |
La vulnerabilità è situata in particolare nella classe KerasFileEditor, responsabile della deserializzazione dei tensori dei pesi del modello dagli archivi HDF5 incorporati negli archivi .keras.
.keras da fonti non attendibili o fornite dall'utente è vulnerabileIl formato file HDF5 memorizza i metadati dei tensori — incluse le dichiarazioni di forma — separatamente dai byte di dati effettivi. Quando KerasFileEditor._extract_weights_from_store() incontra una voce di dataset, legge la forma dichiarata e chiama NumPy per pre-allocare un array con le dimensioni corrispondenti prima di leggere qualsiasi dato dal disco.
Poiché la forma è un metadato, un file HDF5 minimale può dichiarare una forma che richiederebbe petabyte di memoria mentre il file stesso rimane di soli pochi kilobyte. Il rapporto tra dimensione del file e dimensione dell'allocazione rende questo un attacco di amplificazione estremamente efficace.
Una forma come (1000000, 1000000, 1000000) con un dtype float a 32 bit richiederebbe circa 4.000 petabyte di memoria. L'out-of-memory killer del sistema operativo o l'allocatore di Python manderanno in crash il processo quasi istantaneamente.
# 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
L'assenza di qualsiasi controllo su shape prima di chiamare np.zeros() è la causa principale.
Queste informazioni sono fornite esclusivamente a scopo educativo e difensivo. Non testare sistemi che non possiedi o per i quali non hai un'autorizzazione esplicita a testare.
.keras dannoso# generate_shape_bomb.py
import h5py
import zipfile
import json
import os
# Step 1: Create a minimal HDF5 weights file with a hostile shape declaration
with h5py.File("model.weights.h5", "w") as f:
grp = f.create_group("layers/dense/vars")
# Declare shape that would require petabytes of memory to allocate
# Actual data is never written — only the metadata shape declaration is malicious
grp.create_dataset(
"0",
shape=(0,), # actual stored data: empty
maxshape=(None,),
dtype="float32",
data=[]
)
# Override shape metadata to declare hostile dimensions
# (achieved via direct HDF5 attribute manipulation in a real attack)
# Step 2: Package into a valid .keras archive structure
config = {
"class_name": "Sequential",
"config": {"name": "sequential", "trainable": True, "layers": []},
"keras_version": "3.0.0",
"backend": "tensorflow"
}
with zipfile.ZipFile("malicious_model.keras", "w") as zf:
zf.writestr("config.json", json.dumps(config))
zf.writestr("model.weights.h5", open("model.weights.h5", "rb").read())
print("[+] Malicious .keras archive generated: malicious_model.keras")
# trigger.py
import keras
print("[+] Loading malicious model...")
# The crash occurs at load time — no inference required
model = keras.saving.load_model("malicious_model.keras")
print("[-] This line is never reached — interpreter has crashed")
Risultato atteso: L'interprete Python termina con un MemoryError o viene terminato dal gestore out-of-memory del sistema operativo prima che il caricamento venga completato.
Sintomi osservabili:
MemoryError durante load_model() o load_weights()h5dumpLa vulnerabilità è stata risolta dal ricercatore (HyperPS / Sarvesh Patil) nella PR #21880, unita in keras-team:master il 29 dicembre 2025, revisionata e approvata dal manutentore di Keras hertschuh.
| Risorsa | Link |
|---|---|
| Pull Request di correzione | https://github.com/keras-team/keras/pull/21880 |
La patch modifica KerasFileEditor._extract_weights_from_store() in keras/src/saving/file_editor.py aggiungendo le seguenti protezioni prima che avvenga qualsiasi allocazione di memoria:
inner_path durante l'attraversamento ricorsivo dell'archivio HDF5La correzione è retrocompatibile con tutti i file di pesi Keras validi.
# keras/src/saving/file_editor.py (post-fix logic, simplified)
MAX_BYTES = 1 * 1024 ** 3 # 1 GiB hard cap per dataset
MAX_RANK = 64
def _validate_hdf5_dataset_shape(shape, dtype):
"""Reject hostile HDF5 shape declarations before any allocation."""
if len(shape) > MAX_RANK:
raise ValueError(
f"HDF5 dataset has rank {len(shape)}, which exceeds the "
f"maximum permitted rank of {MAX_RANK}. This may indicate "
"a malicious file."
)
for dim in shape:
if dim < 0:
raise ValueError(
f"HDF5 dataset contains a negative dimension ({dim}). "
"This may indicate a malicious file."
)
import math, numpy as np
try:
total_elements = math.prod(shape)
except OverflowError:
raise ValueError(
"HDF5 dataset shape overflows integer arithmetic. "
"This may indicate a malicious file."
)
itemsize = np.dtype(dtype).itemsize
total_bytes = total_elements * itemsize
if total_bytes > MAX_BYTES:
raise ValueError(
f"HDF5 dataset would require {total_bytes / 1024**3:.2f} GiB to "
f"load, which exceeds the 1 GiB safety limit. This may indicate "
"a malicious file."
)
Aggiornamento tramite pip:
pip install --upgrade keras
Verifica della versione installata:
python -c "import keras; print(keras.__version__)"
Pre-scansione di un file di pesi HDF5 per forme sospette:
h5dump --header model.weights.h5 | grep -i "DATASPACE"
Questo repository documenta CVE-2026-0897 esclusivamente a scopo educativo, di ricerca e di sicurezza difensiva. Il codice proof-of-concept e i dettagli tecnici sono forniti per assistere sviluppatori, ingegneri della sicurezza e amministratori di sistema nella comprensione, valutazione e correzione di questa vulnerabilità.
Qualsiasi utilizzo di queste informazioni per causare danni a sistemi, servizi o individui senza autorizzazione esplicita è illegale e non etico. L'autore non si assume alcuna responsabilità per l'uso improprio delle informazioni contenute nel presente documento.
Contributori @mohitf070304
| Metrica | Valore | Significato |
|---|
| Vettore di attacco (AV) | Rete | Sfruttabile da remoto tramite un file di modello distribuito |
| Complessità dell'attacco (AC) | Bassa | Nessuna condizione speciale o race condition richiesta |
| Requisiti di attacco (AT) | Nessuno | Nessuna configurazione di distribuzione prerequisita necessaria |
| Privilegi richiesti (PR) | Nessuno | Nessuna autenticazione o account richiesto |
| Interazione dell'utente (UI) | Passiva | La vittima deve caricare l'archivio .keras dannoso |
| Disponibilità del sistema vulnerabile (VA) | Alta | L'interprete Python va in crash; il servizio diventa completamente non disponibile |
| Riservatezza del sistema vulnerabile (VC) | Nessuna | Nessuna divulgazione di dati |
| Integrità del sistema vulnerabile (VI) | Nessuna | Nessuna modifica dei dati |
| Impatto sui sistemi successivi (SC/SI/SA) | Nessuno | L'impatto è limitato al processo di caricamento |
| Contesto | Rischio |
|---|
API pubbliche di servizio dei modelli che accettano file .keras caricati dagli utenti | L'attaccante manda in crash il servizio di inferenza con una singola richiesta |
| Piattaforme ML che ospitano download di modelli dalla community (es. Hugging Face) | Un modello avvelenato causa DoS per qualsiasi ricercatore che lo scarichi e lo carichi |
| Ambienti di apprendimento federato | Un partecipante malintenzionato distribuisce un file di pesi appositamente creato per mandare in crash il coordinatore o i nodi peer |
| Pipeline CI/CD che caricano checkpoint di modelli | Un checkpoint compromesso o sostituito causa il fallimento della pipeline e l'indisponibilità |
| Chatbot o servizi NLP che ricaricano i modelli a caldo in esecuzione | Una singola richiesta di ricaricamento dannosa manda giù il servizio |
| Commit di merge | 7360d4f |
| Richiesta di backport (3.12.x) | Issue #22031 |
| Azione | Dettagli |
|---|
| Aggiorna Keras | Aggiorna a una versione che includa la correzione della PR #21880 (build master successive alla 3.13.0 o qualsiasi release ufficiale con la patch) |
| Non caricare file di modelli non attendibili | Non caricare mai file .keras o .weights.h5 da fonti non attendibili, non verificate o provenienti dalla community senza una preventiva verifica dell'integrità |
| Verifica l'integrità dei file | Valida i checksum SHA-256 degli archivi di modelli rispetto agli hash forniti dall'editore prima del caricamento |
| Pre-scansione con h5dump | Usa h5dump --header <file> per ispezionare i metadati delle forme dei dataset nei file HDF5 prima di caricarli in Keras |
| Privilegio minimo | Esegui i processi di servizio dei modelli con un utente OS limitato e limiti di memoria imposti tramite cgroups o ulimit per circoscrivere il raggio d'esplosione |
| Containerizzazione | Isola il caricamento dei modelli in un container in sandbox con limiti di memoria per evitare che un singolo crash possa influenzare altri servizi |
| Monitora la memoria | Strumenta le operazioni di caricamento dei modelli per generare avvisi su modelli anomali di allocazione della memoria |
| Data | Evento |
|---|
| 29 novembre 2025 | PR di correzione #21880 inviata a keras-team/keras da HyperPS |
| 1 dicembre 2025 | Il manutentore di Keras hertschuh richiede riferimenti; inizia la revisione |
| 26 dicembre 2025 | Revisione del manutentore completata; riscontri finali affrontati |
| 29 dicembre 2025 | PR #21880 approvata e unita in keras-team:master |
| 15 gennaio 2026 | CVE-2026-0897 pubblicato su NVD |
| 19 gennaio 2026 | Aperta richiesta di backport a Keras 3.12.x (Issue #22031) |
| 23 gennaio 2026 | Record NVD modificato per l'ultima volta |
| Risorsa | Link |
|---|
| Voce NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-0897 |
| Record CVE ufficiale | https://cve.org/CVERecord?id=CVE-2026-0897 |
| Advisory GitHub (GHSA) | https://github.com/advisories/GHSA-xfhx-r7ww-5995 |
| Pull Request di correzione | https://github.com/keras-team/keras/pull/21880 |
| Commit di merge | https://github.com/keras-team/keras/commit/7360d4f0d764fbb1fa9c6408fe53da41974dd4f6 |
| Richiesta di backport | https://github.com/keras-team/keras/issues/22031 |
| Keras su PyPI | https://pypi.org/project/keras/ |
| CWE-770 | https://cwe.mitre.org/data/definitions/770.html |
| Documentazione del formato HDF5 | https://www.hdfgroup.org/solutions/hdf5/ |