Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-12484

CVE-2026-12484: Keras TorchModuleWrapper RCE Vulnerability

CVE-2026-12484 is a remote code execution flaw in Keras 3.15.0 affecting TorchModuleWrapper that allows unsafe PyTorch pickle deserialization. This post explains its technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-12484 Overview

CVE-2026-12484 is an insecure deserialization vulnerability [CWE-502] in keras-team/keras version 3.15.0. The flaw resides in the public keras.layers.TorchModuleWrapper.from_config method, which invokes torch.load(..., weights_only=False) on attacker-controlled data. The method performs unsafe PyTorch pickle deserialization by default when called outside a SafeModeScope(True) context. Processing an untrusted Keras layer configuration through this path can result in arbitrary code execution on the host running the model loader.

Critical Impact

An attacker who supplies a crafted Keras layer configuration can execute arbitrary code in the context of the process loading the model, leading to full compromise of the local user account.

Affected Products

  • keras-team/keras version 3.15.0
  • Applications embedding Keras 3 that call TorchModuleWrapper.from_config on untrusted input
  • ML pipelines and model registries that deserialize third-party Keras layer configs

Discovery Timeline

  • 2026-07-19 - CVE-2026-12484 published to NVD
  • 2026-07-23 - Last updated in NVD database

Technical Details for CVE-2026-12484

Vulnerability Analysis

The vulnerability sits in Keras 3's PyTorch interoperability layer. TorchModuleWrapper.from_config reconstructs a wrapped torch.nn.Module by calling torch.load on a byte buffer carried inside the config dictionary. The call passes weights_only=False, which instructs PyTorch to use the full pickle deserializer rather than the restricted tensor-only loader.

Pickle deserialization executes arbitrary constructors and __reduce__ methods embedded in the stream. An attacker who controls the config payload can therefore trigger execution of any Python callable, including os.system or subprocess.Popen, at load time. Exploitation requires user interaction, such as loading a model file or config supplied by a third party.

Root Cause

The root cause is missing enforcement of Keras safe mode inside from_config. Keras exposes SafeModeScope and a safe_mode parameter elsewhere in its serialization API to block unsafe primitives such as lambda deserialization and torch.load with pickle. TorchModuleWrapper.from_config neither consults the ambient SafeModeScope state nor accepts an explicit safe_mode argument. When invoked outside a safe-mode context, deserialization defaults to unsafe behavior.

Attack Vector

Exploitation is local and requires user interaction. A typical attack chain distributes a malicious Keras model artifact, for example a .keras archive or a JSON config referencing a TorchModuleWrapper layer. When a data scientist or automated pipeline loads the model, from_config is invoked and the embedded pickle payload runs with the privileges of the loading process. Public model hubs, shared notebooks, and CI systems that ingest external models are the most exposed environments.

No verified public exploit code has been published. See the Huntr Bounty Report for the disclosure details.

Detection Methods for CVE-2026-12484

Indicators of Compromise

  • Python processes spawning shells (sh, bash, cmd.exe, powershell.exe) as children of interpreters that recently loaded a Keras or PyTorch model
  • Outbound network connections initiated by Python processes immediately after keras.models.load_model or from_config calls
  • Unexpected files written to home directories, /tmp, or %TEMP% following model load operations
  • Presence of TorchModuleWrapper entries in third-party model configs sourced from untrusted registries

Detection Strategies

  • Instrument Python environments with import hooks that log invocations of torch.load where weights_only=False
  • Perform static scanning of .keras, .h5, and JSON config files for TorchModuleWrapper class references before loading
  • Use pickle scanners such as picklescan or fickling against any model archive received from external sources
  • Correlate process telemetry to flag Python interpreters that execute non-ML binaries after model loading events

Monitoring Recommendations

  • Enable command-line and process-lineage logging on hosts that train or serve models, including data science workstations and CI runners
  • Alert on Python processes writing to autostart locations, cron entries, or SSH authorized_keys files
  • Track egress from ML training hosts to non-approved destinations, especially raw IPs and paste sites

How to Mitigate CVE-2026-12484

Immediate Actions Required

  • Inventory environments running keras 3.15.0 and identify code paths that call TorchModuleWrapper.from_config
  • Block ingestion of Keras models from untrusted sources until a patched release is deployed
  • Wrap all deserialization of external configs in an explicit SafeModeScope(True) context
  • Rotate credentials and inspect endpoints that previously loaded third-party models containing TorchModuleWrapper layers

Patch Information

At the time of publication, the enriched CVE record does not list a fixed version. Track the Huntr Bounty Report and the upstream keras-team/keras repository for an updated release that enforces safe mode inside TorchModuleWrapper.from_config or requires an explicit safe_mode=False opt-in.

Workarounds

  • Load third-party models only inside a with keras.config.SafeModeScope(True): block to force safe deserialization
  • Replace TorchModuleWrapper layers in received configs with locally trusted equivalents before loading
  • Run model-loading workloads inside sandboxed containers with no network egress and read-only filesystems
  • Restrict model repositories to internally signed artifacts and enforce checksum verification before loading
bash
# Configuration example: force Keras safe mode when loading external models
export KERAS_SAFE_MODE=1
python - <<'PY'
import keras
with keras.config.SafeModeScope(True):
    model = keras.models.load_model("/path/to/untrusted_model.keras")
PY

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.