CVE-2026-12484: Keras Unsafe Deserialization Vulnerability
TL;DR - Keras 3.15.0 contains an unsafe deserialization flaw in
keras.layers.TorchModuleWrapper.from_config. - Risk is highest where untrusted model or layer configs are imported. - Treat as urgent if your ML pipeline ingests third-party artifacts; patch status is not fully confirmed from available sources.
Vulnerability at a Glance
| Field | Value |
|---|---|
| CVE ID | CVE-2026-12484 |
| CVSS | 7.8 |
| Attack vector | Not explicitly confirmed in the retrieved primary-source data; practical exploitation requires processing attacker-controlled configuration data |
| Privileges required | None stated in the retrieved source material; defenders should assume exploitation depends on the application’s import workflow rather than prior account compromise |
| Patch available | Unknown from retrieved primary sources |
This issue affects Keras through unsafe deserialization of attacker-controlled PyTorch pickle data. The NVD description states that keras.layers.TorchModuleWrapper.from_config may invoke torch.load(..., weights_only=False) without requiring an explicit unsafe opt-in. In Python and ML stacks, that pattern is dangerous because pickle-compatible loaders can execute code while reconstructing crafted objects.
For practitioners, the important point is not just that Keras is affected, but that the vulnerable path sits in model or layer loading logic. That means the risk depends heavily on whether your environment accepts external Keras configurations, third-party model artifacts, or user-submitted ML components. In notebook servers, model registries, CI jobs, and inference pipelines, “loading a model” can effectively become “executing attacker-influenced code” if the input is untrusted.
What Is This Vulnerability?
CVE-2026-12484 is an unsafe deserialization vulnerability that can lead to arbitrary code execution. According to the NVD description, the flaw exists in keras.layers.TorchModuleWrapper.from_config, which uses torch.load(..., weights_only=False) in a way that does not force an explicit unsafe opt-in. When untrusted serialized content reaches that code path, deserialization can trigger execution of attacker-controlled pickle payloads.
The root cause is not a classic memory corruption bug. It is a trust-boundary failure in application logic. Python pickle-based formats are not safe for untrusted input, and PyTorch serialization has long carried that warning. When a framework method loads serialized objects rather than strictly limited weight tensors or plain data structures, an attacker can abuse object reconstruction hooks to run code during deserialization.
In this case, the NVD description further notes that exploitation becomes possible when processing occurs outside a SafeModeScope(True) context. That matters because the vulnerable behavior appears to depend on the absence of Keras safe-mode protections. If an application or service handles attacker-controlled Keras layer configurations without enforcing safe mode, the deserialization path may proceed in an unsafe default state.
Technical Notes
The vulnerable behavior described publicly centers on this pattern:
# Risk pattern described by NVD
keras.layers.TorchModuleWrapper.from_config(...)
# internally reaches
torch.load(..., weights_only=False)
Why that matters operationally:
# Safe handling principle
# Do not load untrusted pickle-based model artifacts.
# Restrict imports to trusted, signed, internally produced artifacts only.
Who Is Affected?
The only version explicitly confirmed in the retrieved primary-source material is Keras 3.15.0. The research note does not establish a broader affected range, and the available source set does not confirm whether earlier 3.x releases or later builds are also vulnerable. Because of that, defenders should avoid extrapolating beyond what is documented.
Stated conservatively, the confirmed affected product/version is:
- Product: Keras (
keras-team/keras) - Confirmed affected version: 3.15.0
- Fixed version: Not confirmed from retrieved primary sources
If you run Keras 3.15.0 anywhere in your environment, especially in systems that ingest untrusted or semi-trusted ML artifacts, you should assume exposure until you validate otherwise. That includes managed notebooks, internal model-sharing portals, MLOps pipelines, CI systems that test user-contributed models, and hosted services that import customer-supplied model components.
Even if your environment does not intentionally accept public uploads, this CVE still matters in supply-chain scenarios. Teams often pull pretrained models, example repositories, research artifacts, and serialized components from external sources. A vulnerable import path inside a trusted internal workflow can still be enough for code execution if the artifact origin is not tightly controlled.
CVSS Score Breakdown
The reported CVSS base score is 7.8, which places this issue in the high-severity range. The full CVSS vector was not returned in the NVD tool output provided, so any deeper breakdown must be treated as incomplete. Still, the score aligns with the documented impact: arbitrary code execution through unsafe deserialization is typically treated as severe because compromise can occur during normal processing, not only through an obvious “run this script” action.
In practical terms, a 7.8 score suggests a serious issue with substantial impact to confidentiality, integrity, and availability if exploitation succeeds. Arbitrary code execution in ML environments can expose training data, model weights, credentials, cloud metadata, tokens for package registries, and CI secrets. It can also let an attacker modify models, poison outputs, or pivot deeper into the environment.
What remains unclear from the available data is the precise scoring around attack vector and user interaction. The vulnerability may depend on an application importing attacker-controlled configuration data, which often means the score reflects realistic but conditional exploitation. Defenders should not downplay that condition: in modern AI and MLOps environments, importing external artifacts is common enough that “requires crafted input” is still operationally meaningful risk.
Exploitation Status
At the time of writing, there is no confirmed evidence of active exploitation in the wild from the source material provided. The CVE is not listed in CISA’s Known Exploited Vulnerabilities catalog, which means there is no current KEV-backed confirmation of in-the-wild abuse.
There is also no confirmed public proof-of-concept (PoC) identified in the retrieved source set. That does not mean exploit development is difficult. Unsafe deserialization through pickle-compatible loaders is a well-understood attack class, and the dangerous behavior is described clearly enough that independent researchers may be able to reproduce it if they have access to the affected environment.
For defenders, the right takeaway is: neither active exploitation nor a public PoC is confirmed from available sources, but the exploit path is credible and technically straightforward in principle. If your workflows accept externally supplied Keras configs or artifacts, do not wait for a KEV listing before acting.
Technical Notes
Operational assumptions when exploit intelligence is incomplete:
Known public PoC: Not confirmed
Known in-the-wild exploitation: Not confirmed
CISA KEV listed: No
Defender assumption model:
If your pipeline loads third-party Keras configs or model wrappers,
treat this as a reachable code-execution path until a fixed version
or vendor remediation note is confirmed and deployed.
How to Detect It
Detection is partly about version inventory and partly about tracing model-loading behavior. Start by identifying all environments running Keras 3.15.0. Then prioritize systems that import model or layer configuration data from outside the trust boundary: public uploads, partner exchanges, internal multi-tenant notebooks, CI artifacts, or downloaded pretrained components.
Because this is a deserialization issue, network-only detection may be weak unless you know how malicious artifacts are delivered. Application and host telemetry are more useful. Look for processes that load Keras or PyTorch artifacts and then unexpectedly spawn shells, Python subprocesses, curl/wget, package installers, or outbound connections. On shared ML infrastructure, suspicious behavior shortly after model import is a strong hunting lead.
You should also review code paths that call keras.layers.TorchModuleWrapper.from_config directly or indirectly. If your codebase, plugins, notebooks, or services reconstruct Keras layer configs from untrusted JSON, YAML, database records, or user uploads, that is a direct exposure indicator even if you do not yet have signs of compromise.
Technical Notes
Example code search:
grep -R "TorchModuleWrapper.from_config" /srv/apps /opt/repos /home/*/notebooks 2>/dev/null
grep -R "SafeModeScope" /srv/apps /opt/repos /home/*/notebooks 2>/dev/null
Example package inventory checks:
python -m pip show keras
python -c "import keras; print(keras.__version__)"
pip freeze | grep -E '^keras=='
Example EDR/SIEM hunting ideas for suspicious child processes from Python after model loading:
DeviceProcessEvents
| where InitiatingProcessFileName in~ ("python", "python3")
| where ProcessCommandLine has_any ("curl ", "wget ", "bash -c", "sh -c", "powershell", "nc ")
| where Timestamp > ago(14d)
Example Splunk search for suspicious Python execution following model import activity:
index=process_logs (parent_process_name=python OR process_name=python OR process_name=python3)
(process_command_line="*curl *" OR process_command_line="*wget *" OR process_command_line="*bash -c*" OR process_command_line="*sh -c*")
Concrete log pattern to watch for in application logs or notebook histories:
TorchModuleWrapper.from_config
torch.load(
weights_only=False
SafeModeScope(False)
If your logging captures stack traces or debug events, any occurrence tying TorchModuleWrapper.from_config to untrusted artifact import should be escalated for review.
Mitigation and Patching
The most important limitation here is that the fixed version number is not confirmed from the retrieved primary sources. The available material confirms Keras 3.15.0 as affected but does not authoritatively identify the patched release. Because the user asked for the fixed version number, the accurate answer is: unknown at this time from the sources provided. Defenders should not guess. Instead, monitor the Keras project repository and security advisories for a confirmed fix before standardizing on a target version.
Until a vendor-confirmed fixed version is published, the safest mitigation is to stop processing untrusted Keras layer configurations and serialized PyTorch-backed artifacts in vulnerable environments. If your workflow must accept third-party artifacts, isolate model loading in hardened sandboxes with no secrets, no cloud instance metadata access, no privileged mounts, and tightly restricted outbound network access. Treat imported model content the same way you would treat untrusted code.
You should also enforce safe-mode usage where available and review whether your code or dependencies invoke TorchModuleWrapper.from_config outside a SafeModeScope(True) context. If that path is not required, disable or remove it from exposed workflows. If it is required, limit usage to trusted internally generated artifacts only.
Technical Notes
Example immediate containment by pinning away from the confirmed vulnerable version, if your testing supports it and once you validate compatibility:
# Do not treat this as the confirmed fixed version.
# This only avoids installing the explicitly confirmed vulnerable build.
pip install "keras!=3.15.0"
Example to hold the current environment and prevent further risky imports until remediation is decided:
# Example operational workaround
# 1) Freeze current package state
pip freeze > requirements.freeze.txt
# 2) Disable artifact ingestion job or model import worker
systemctl stop model-import-worker
systemctl disable model-import-worker
Example code-level mitigation principle:
# Pseudocode: reject untrusted external model/layer configs
def import_layer_config(config, source_trust):
if source_trust != "trusted-internal":
raise ValueError("External Keras layer configs are temporarily blocked")
Example environment hardening for model loaders:
# Run import jobs in isolated containers with no network and no mounted secrets
docker run --rm \
--network none \
--read-only \
--cap-drop ALL \
-v /tmp/import:/work \
your-ml-importer:latest
When a Keras advisory or release note confirms the patched version, update your dependency manifests explicitly:
# Replace X.Y.Z with the vendor-confirmed fixed release once published
pip install --upgrade "keras==X.Y.Z"
In the absence of a confirmed fixed version, that placeholder is the most accurate instruction. Anything more specific would be guesswork.
References
The primary public description comes from the NVD summary reflected in the research note. That description identifies the vulnerable method, the dangerous torch.load(..., weights_only=False) behavior, the role of SafeModeScope(True), and the confirmed affected version 3.15.0. It also establishes the impact as arbitrary code execution when untrusted Keras layer configurations are processed through the vulnerable path.
For further reading on related vulnerabilities, check out these resources: - CVE-2026-44050 - CVE-2026-45087
This article may contain affiliate links. We earn a commission on qualifying purchases at no extra cost to you.