CVE-2025-49655
Python vulnerability analysis and mitigation

Overview

CVE-2025-49655 is a critical deserialization of untrusted data vulnerability in the Keras deep learning framework affecting versions 3.11.0 up to but not including 3.11.3. The flaw allows a maliciously crafted Keras file containing a TorchModuleWrapper class to execute arbitrary code on an end user's system when loaded, even when Keras's safe mode is enabled. The vulnerability was discovered and reported by HiddenLayer, published on October 17, 2025, and assigned a CVSS v3.1 base score of 9.8 (Critical) (Github Advisory, HiddenLayer).

Technical details

The root cause is improper handling of PyTorch's torch.load() function within the TorchModuleWrapper.from_config method (CWE-502: Deserialization of Untrusted Data). Keras's safe mode was intended to prevent arbitrary code execution during model loading, but it failed to restrict torch.load() calls in the TorchModuleWrapper class, which uses Python's pickle-based deserialization internally — a well-known vector for arbitrary code execution. The vulnerability can be triggered by loading a specially crafted Keras model file from either local or remote sources, requiring no authentication or user interaction beyond the act of loading the file. The fix, merged in PR #21575, raises a ValueError when torch.load() is attempted while in_safe_mode() is active (Keras PR #21575, Github Advisory).

Impact

Successful exploitation results in full compromise of the target system's confidentiality, integrity, and availability, as an attacker can execute arbitrary code with the privileges of the process loading the Keras model. This is particularly dangerous in ML pipeline environments where models are routinely loaded from shared repositories, model hubs, or remote storage, enabling supply chain attacks against data scientists and ML engineers. An attacker who can deliver a malicious model file — for example, by uploading it to a shared model repository or intercepting a remote model download — can achieve remote code execution without any user interaction beyond the normal model loading workflow (Github Advisory, HiddenLayer).

Exploitability

As of the time of disclosure, there is no public proof-of-concept exploit and no confirmed evidence of in-the-wild exploitation (Feedly). The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The EPSS score is approximately 0.041–0.048%, placing it in the 15th percentile for exploitation likelihood within 30 days (Github Advisory). However, the attack vector is network-accessible, requires no privileges or user interaction, and targets a widely used ML framework, making it a high-priority patching target for organizations using Keras with PyTorch backends.

Exploitation steps

  1. Craft a malicious Keras model file: Create a Keras-format model file (e.g., .keras or .h5) that includes a TorchModuleWrapper layer whose serialized state embeds a malicious Python pickle payload — for example, a payload that spawns a reverse shell or executes a system command when deserialized via torch.load().
  2. Deliver the malicious file: Upload the crafted model file to a shared model repository, model hub (e.g., Hugging Face), cloud storage bucket, or serve it from an attacker-controlled server. Alternatively, perform a man-in-the-middle attack to substitute a legitimate model download with the malicious file.
  3. Trigger model loading on the victim system: Wait for or socially engineer a target running Keras 3.11.0–3.11.2 to load the malicious model file using keras.models.load_model() or equivalent API — even with safe_mode=True enabled.
  4. Achieve arbitrary code execution: When TorchModuleWrapper.from_config calls torch.load() on the embedded PyTorch module state, the pickle payload is deserialized and the attacker's code executes with the privileges of the Python process, enabling data exfiltration, persistence, or lateral movement within the ML infrastructure (Keras PR #21575, HiddenLayer).

Indicators of compromise

  • Network: Unexpected outbound connections (reverse shells, beaconing) from Python/Keras processes to unknown external IPs after model loading operations; unusual DNS lookups from ML workstations or servers.
  • File System: Unexpected new files (scripts, binaries, cron jobs) created by the Python process running Keras; presence of unfamiliar .keras or .h5 model files in model directories, especially those downloaded from external sources.
  • Logs: Python process logs or system logs showing errors or exceptions related to TorchModuleWrapper deserialization; unexpected child processes (e.g., bash, sh, curl, wget) spawned by a Python interpreter.
  • Process: Unusual child processes created by the Python/Keras process, particularly shell interpreters or network utilities; elevated CPU or network activity immediately following a keras.models.load_model() call.

Mitigation and workarounds

The primary remediation is to upgrade the Keras framework to version 3.11.3 or later, which disables torch.load() within TorchModuleWrapper when safe mode is active and raises a descriptive ValueError (Keras PR #21575, Github Advisory). Until patching is possible, organizations should restrict the sources from which Keras model files are loaded, implement strict allowlisting of model file origins, and avoid loading models from untrusted or unverified sources. Additional mitigations include sandboxing model loading operations (e.g., in isolated containers or VMs), monitoring file upload and model loading activities, and temporarily disabling PyTorch-backend model loading if not required (HiddenLayer).

Community reactions

HiddenLayer, the CNA that assigned and disclosed this CVE, published a security advisory detailing the vulnerability and its impact on ML pipelines (HiddenLayer). Security news outlet SecurityOnline.info covered the flaw, highlighting the critical CVSS score and the risk of code execution on model load as particularly concerning for the ML/AI community (SecurityOnline). The vulnerability also attracted attention on Bluesky within the infosec community, and a Tsunami Security Scanner plugin was proposed (though later closed) to detect vulnerable instances, reflecting broader interest in automated detection (Feedly).

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-54569CRITICAL9.8
  • Python logoPython
  • senaite.core
NoNoAug 26, 2026
CVE-2026-54553MEDIUM5.4
  • Python logoPython
  • starlette-admin
NoYesAug 26, 2026
GHSA-x287-5c68-36wpMEDIUM5.3
  • Python logoPython
  • openwisp-ipam
NoYesAug 26, 2026
CVE-2026-54548LOW3.3
  • Python logoPython
  • kas
NoYesAug 26, 2026
GHSA-93qj-5q5v-3c2hCRITICALN/A
  • Python logoPython
  • pantheon-agents
NoYesAug 26, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management