CVE-2026-0897: Keras Model Load “Memory Bomb” – One File Can Crash Your ML Service

CVE ID: CVE-2026-0897
Product: Google Keras
Vulnerability Type: Memory Exhaustion / Denial of Service (DoS)
Severity: High
CVSS Score: 7.1 (High)
Attack Vector: Network (via untrusted model files)
Exploitability: Low complexity, no privileges required
Exploit Availability: No mature public exploit; proof-of-concept possible for educational/research purposes
Impact: Service crash, container restart loops, application unavailability


What this vulnerability is

This vulnerability exists in how Keras loads model weight files stored in HDF5 (.h5) format inside a .keras model archive.
When Keras loads a model, it reads metadata from the HDF5 file that describes tensor shapes and sizes. In vulnerable versions, Keras trusts this metadata blindly.

An attacker can craft a malicious .keras file where the HDF5 dataset claims to have extremely large tensor dimensions (for example, trillions of elements).
Keras then attempts to allocate memory based on those declared dimensions.

The result:

  • The Python process attempts to allocate massive memory
  • System RAM is exhausted
  • The process crashes or is killed by the OS (OOM killer)
  • The application becomes unavailable

There is no code execution, but the service can be taken down reliably.


Affected Versions

  • Keras versions: 3.0.0 up to 3.13.0
  • Any application that loads .keras models from untrusted or semi-trusted sources is at risk

How an attacker could realistically exploit this

  1. The attacker creates a .keras file containing a manipulated model.weights.h5
  2. Inside the HDF5 file, dataset headers declare huge tensor shapes
  3. The attacker convinces a user, service, or pipeline to load the model:
    • Model zoo
    • CI/CD pipeline
    • Automated ML workflow
    • User-uploaded model feature
  4. Keras tries to load the weights
  5. Memory allocation explodes
  6. Application crashes → Denial of Service

This is especially dangerous in:

  • Model marketplaces
  • ML platforms
  • APIs that auto-load uploaded models
  • Kubernetes environments (causes CrashLoopBackOff)

Why this happens

  • HDF5 allows datasets to describe shapes independently of actual stored data
  • Keras did not enforce upper bounds on:
    • Tensor dimensions
    • Total allocation size
  • NumPy attempts to allocate memory based on metadata alone

This is a classic case of unbounded resource allocation.


MITRE Mapping

  • CWE-770 – Allocation of Resources Without Limits or Throttling
  • Impact Category: Availability
  • Threat Class: Application-level Denial of Service

Is there a PoC or exploit? (educational)

  • There is no widely weaponized exploit published
  • However, creating a PoC is trivial for anyone familiar with h5py
  • A PoC involves crafting an HDF5 dataset with absurd dimensions (shape bomb)
  • This is considered educational / research-level exploitation

The exploit requires the victim to load the malicious model. There is no drive-by or remote code execution.


How to detect exploitation or attempted abuse

Behavioral indicators

  • Sudden memory spikes when loading a model
  • Python process killed unexpectedly
  • Kernel OOM messages
  • Repeated container restarts
  • Model load failures without clear validation errors

Key log sources

  • Application logs (Python stack traces)
  • Container runtime logs (Docker / Kubernetes)
  • Host OS logs (dmesg, syslog)
  • ML pipeline execution logs

Splunk Detection Rules

Rule 1 – Memory exhaustion during Keras model load

index=application_logs
(message="keras.models.load_model" OR message="KerasFileEditor" OR message="h5py")
| transaction maxspan=2m
| search message="MemoryError" OR message="Out of memory" OR message="Killed process"
| table _time host process message file_path

Rule 2 – Kubernetes container OOM after model load

index=kubernetes_logs
(message="OOMKilled" OR message="Killed container")
| search previous_message="load_model" OR previous_message="model.weights.h5"
| table _time namespace pod container message

Rule 3 – Abnormal memory spike (metrics-based)

index=metrics
metric_name=process_resident_memory_bytes
| delta value as mem_spike
| where mem_spike > 1073741824
| table _time host process mem_spike

Pre-Load Python Scanner

Use this before calling keras.models.load_model().

This scanner inspects HDF5 metadata only and never allocates tensors.

import h5py
import numpy as np

MAX_BYTES = 1 * 1024**3  # 1 GiB safety limit
MAX_DIMS = 8            # reasonable upper bound

def is_safe_hdf5_weights(h5_path):
    with h5py.File(h5_path, "r") as f:
        def check_dataset(name, obj):
            if isinstance(obj, h5py.Dataset):
                if len(obj.shape) > MAX_DIMS:
                    raise ValueError(f"Too many dimensions: {obj.shape}")

                size = np.dtype(obj.dtype).itemsize
                for dim in obj.shape:
                    size *= int(dim)
                    if size > MAX_BYTES:
                        raise ValueError(
                            f"Dataset '{name}' would allocate {size} bytes"
                        )

        f.visititems(check_dataset)

    return True

# Example usage
try:
    is_safe_hdf5_weights("model.weights.h5")
    print("Model appears safe to load")
except Exception as e:
    print(f"Blocked unsafe model: {e}")

Best practice:
Reject the model immediately if this check fails.


Recommended Mitigations

  1. Upgrade Keras immediately
    Apply the official upstream fix. Official patch / fix link:
    👉 https://github.com/keras-team/keras/pull/21880
  2. Never auto-load untrusted models
    Treat model files like executable content.
  3. Add metadata validation
    Use the pre-load scanner above.
  4. Sandbox model loading
    • Load models in isolated workers
    • Apply memory limits (cgroups / Kubernetes limits)
  5. Monitor aggressively
    • Alert on memory spikes
    • Alert on repeated model load failures
  6. Set size expectations
    • Define maximum allowed tensor sizes
    • Enforce organizational standards for model artifacts

Why this vulnerability matters

Machine learning pipelines often assume models are “just data.”
This vulnerability proves they can be attack vectors.

Even without code execution, a single malicious model can:

  • Take down production services
  • Break CI/CD pipelines
  • Cause cascading failures in distributed ML systems

Any environment that loads third-party or user-supplied models should treat this as high risk.


Aegiron

Backed by 11+ years in cybersecurity and incident response, we decode the latest threats shaping today’s digital battlefield. This blog cuts through the noise with clear insights on vulnerabilities, emerging exploits, and the cyber news defenders can’t afford to miss.