Severity by source
AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Exploitation needs a victim to load an untrusted config (AV:L, UI:R) with no auth (PR:N), and unpickling yields full code execution, so C/I/A all High.
Primary rating from Vendor (huntr).
CVSS VectorVendor: huntr
CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Lifecycle Timeline
2Blast Radius
ecosystem impact- 1 pypi packages depend on keras (1 direct, 0 indirect)
Ecosystem-wide dependent count for version 3.13.0.
DescriptionCVE.org
A vulnerability in keras-team/keras version 3.15.0 allows unsafe deserialization of attacker-controlled PyTorch pickle data through the public keras.layers.TorchModuleWrapper.from_config method. This method invokes torch.load(..., weights_only=False) without requiring an explicit unsafe opt-in, such as a safe_mode=False parameter. When called outside a SafeModeScope(True) context, the absence of an ambient safe mode state permits unsafe deserialization by default. This issue can lead to arbitrary code execution if untrusted Keras layer configurations are processed using this method. The vulnerability arises because the method does not enforce safe deserialization practices unless explicitly guarded by Keras safe mode.
AnalysisAI
Arbitrary code execution in keras-team/keras 3.15.0 arises because the public keras.layers.TorchModuleWrapper.from_config method calls torch.load(..., weights_only=False) without any explicit unsafe opt-in, so a maliciously crafted Keras layer configuration deserialized outside a SafeModeScope(True) context triggers execution of attacker-controlled PyTorch pickle payloads (CWE-502). Any application or pipeline that loads untrusted or third-party Keras model/layer configs is affected; CVSS is 7.8 (High) with a local vector requiring user interaction. There is no public exploit identified at time of analysis and the flaw is not listed in CISA KEV, but the vulnerability class is well understood and reliably weaponizable via standard pickle reduce gadgets.
Technical ContextAI
Keras is a high-level neural-network API; version 3 (Keras Core) supports multiple backends including PyTorch, and TorchModuleWrapper is the adapter that embeds a native torch.nn.Module inside a Keras layer. Model/layer serialization in Keras round-trips through get_config/from_config dictionaries, and for the Torch wrapper the persisted state is restored via torch.load. PyTorch's torch.load defaults to the pickle protocol, and with weights_only=False it will unpickle arbitrary Python objects - invoking __reduce__ methods that can run any code during load. The root cause (CWE-502, Deserialization of Untrusted Data) is that from_config performs this unsafe load unconditionally: Keras has a safe-mode mechanism (SafeModeScope) intended to block unsafe deserialization, but this code path only honors it when a SafeModeScope(True) is already active and provides no per-call safe_mode=False gate, so the insecure behavior is the default rather than an explicit, audited opt-in.
RemediationAI
No vendor-released patch version is identified in the provided data, so a specific fixed release cannot be cited - consult the huntr advisory (https://huntr.com/bounties/ab14df49-13b5-4442-b754-3189430bfa28) and the keras-team/keras releases for an upgraded version and apply it once published. As the primary compensating control, never call TorchModuleWrapper.from_config (or deserialize Keras models/layers) on configurations from untrusted or unverified sources; treat model files like executable code. Where deserialization of external configs is unavoidable, wrap the operation in a SafeModeScope(True) context so Keras safe mode blocks the unsafe torch.load path - with the trade-off that legitimate configs relying on that Torch-wrapper load will fail and must be sourced only from trusted parties. Additionally, isolate model-loading in a sandboxed, least-privilege process or container without network egress or sensitive credentials to limit blast radius if a hostile config is loaded, accepting the added operational complexity of a separate deserialization service.
Same weakness CWE-502 – Deserialization of Untrusted Data
View allVendor StatusVendor
Share
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-45872
GHSA-v2w2-w228-c444