CVE-2026-12481 Overview
CVE-2026-12481 is an insecure deserialization vulnerability in Keras 3.14.0 that allows arbitrary code execution through the Lambda layer. The flaw resides in the _raise_for_lambda_deserialization() function, which fails to enforce the safe-mode guard when safe_mode is set to None. This logic error treats the default-deny None value the same as an explicitly disabled False, bypassing protections against untrusted marshal bytecode. Attackers can achieve OS-level code execution by supplying a malicious model configuration to keras.layers.deserialize(), keras.models.clone_model(), or Lambda.from_config() outside a SafeModeScope(True) context. The vulnerability is tracked under [CWE-502] Deserialization of Untrusted Data.
Critical Impact
Remote attackers can execute arbitrary operating system commands in the context of the server or user process by supplying a crafted Keras model configuration.
Affected Products
- Keras 3.14.0
- Applications embedding keras.layers.Lambda deserialization paths
- ML pipelines invoking keras.models.clone_model() on untrusted models
Discovery Timeline
- 2026-07-03 - CVE-2026-12481 published to NVD
- 2026-07-08 - Last updated in NVD database
Technical Details for CVE-2026-12481
Vulnerability Analysis
The vulnerability originates in the safe-mode enforcement logic within Keras 3.14.0's Lambda layer deserialization path. The _raise_for_lambda_deserialization() helper is designed to block loading of marshal-encoded Python bytecode unless the caller explicitly opts in. The check evaluates safe_mode using a boolean comparison that treats None as permissive rather than as an unset default that should deny deserialization.
When from_config() executes outside an enclosing SafeModeScope, safe_mode remains None. The guard function skips the exception path and proceeds to marshal.loads() on attacker-controlled bytes. This grants execution of arbitrary Python code during model reconstruction, which the interpreter then runs with the privileges of the host process.
Affected entry points include keras.layers.deserialize(config), keras.models.clone_model(model), and direct Lambda.from_config(config) calls. Any server, notebook, or pipeline that ingests third-party Keras artifacts is exposed.
Root Cause
The root cause is a conflation of tri-state semantics. The code interprets None (unset) identically to False (explicitly disabled) when it should apply a default-deny policy. This weakens the safe-mode contract intended to isolate marshal deserialization behind explicit developer consent.
Attack Vector
An attacker publishes or delivers a malicious Keras model or serialized layer configuration containing a Lambda layer whose function payload is crafted marshal bytecode. When a downstream user or automated pipeline loads or clones the model without wrapping the call in SafeModeScope(True), the payload deserializes and executes. The attack requires no authentication and no user interaction beyond loading the model file.
Technical details are available in the Huntr Bug Bounty Report.
Detection Methods for CVE-2026-12481
Indicators of Compromise
- Keras model files (.keras, .h5, JSON configs) containing Lambda layers with embedded marshal bytecode in the function field
- Python processes spawning unexpected child processes (sh, bash, cmd.exe, powershell.exe) from ML training or inference workloads
- Outbound network connections initiated by Python interpreters immediately after model load operations
Detection Strategies
- Inspect model configuration JSON for Lambda layer entries whose config.function field contains base64-encoded binary data rather than plain function references
- Instrument Python runtimes to log calls to keras.layers.deserialize, keras.models.clone_model, and Lambda.from_config and alert on invocations outside a SafeModeScope(True) context
- Correlate ML workload process trees against a baseline to identify anomalous execve, fork, or CreateProcess events originating from model deserialization
Monitoring Recommendations
- Log the SHA-256 hash and source of every model artifact loaded in production, and cross-reference against an allowlist of trusted publishers
- Monitor file integrity on directories holding Keras models and alert on writes from unexpected identities
- Enable egress network monitoring on ML inference hosts to catch reverse shells or data exfiltration attempts triggered by malicious deserialization
How to Mitigate CVE-2026-12481
Immediate Actions Required
- Upgrade Keras beyond version 3.14.0 to a release that enforces default-deny semantics on safe_mode
- Audit all code paths calling keras.layers.deserialize, keras.models.clone_model, and Lambda.from_config and wrap them in SafeModeScope(True)
- Quarantine and re-verify any Keras models received from external or untrusted sources before loading them into production
- Restrict outbound network access from hosts running ML inference and training jobs
Patch Information
At the time of publication, no vendor advisory URL is listed in the NVD entry. Refer to the Huntr Bug Bounty Report for coordinated disclosure details and monitor the keras-team/keras repository for a fixed release superseding 3.14.0.
Workarounds
- Wrap every deserialization call in an explicit with SafeModeScope(True): block until an upstream fix is available
- Reject or strip Lambda layers from third-party model configurations at ingest time, replacing them with reviewed native layer implementations
- Execute untrusted model loads inside sandboxed containers with no network access and read-only filesystems to contain arbitrary code execution
# Enforce safe-mode deserialization in application code
python -c "from keras.saving import SafeModeScope; \
import keras; \
with SafeModeScope(True): \
model = keras.models.load_model('untrusted_model.keras')"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

