YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
PyTorch Export Serialize Fallback RCE (Incomplete Fix Bypass)
Format: Torch Export (.pt2) β PyTorch
Project: PyTorch (pytorch/pytorch)
Version: 2.12.0
Severity: Critical β RCE on model load
CVE Context
- CVE-2024-42480 (PyTorch < 2.5.1) was assigned to this vulnerability.
- The "fix" in 2.5.1 changed the first
torch.load()attempt to useweights_only=True, but theexceptfallback still usesweights_only=False. - This is an incomplete fix: an attacker can craft a payload that fails the
weights_only=Trueattempt (e.g., using blocked globals) and the fallback loads it unsafely. - Vulnerability is still present in PyTorch 2.12.0.
Description
deserialize_torch_artifact() in torch/_export/serde/serialize.py:422-445 first tries weights_only=True, and on any exception falls back to weights_only=False:
try:
artifact = torch.load(buffer, weights_only=True) # line 437
except Exception as e:
buffer.seek(0)
artifact = torch.load(buffer, weights_only=False) # line 440 β FALLBACK!
An attacker crafts data/sample_inputs/model.pt in a .pt2 archive that references os.system (blocklisted). The weights_only=True path fails β falls back to weights_only=False β standard pickle.load() executes the payload.
Key Detail
When weights_only=False, torch.load() calls _legacy_load() which does pickle_module.load(f) at serialization.py:1887 β this is a full unpickling operation that executes the malicious pickle before checking the magic number.
Impact
Any user calling torch.export.load("malicious.pt2") gets RCE. This is a separate code path from the weights loading RCE in _package.py:877.
Steps to Reproduce
python poc_serialize_fallback.py --cmd "echo PWNED" --test-load
Output:
[!] weights_only=True β Exception β weights_only=False
[!] Post-exploitation error: RuntimeError: ...
But the command already executed (check PWNED output).
How It Works
- Create a valid PT2 archive
- Replace
data/sample_inputs/model.ptwith pickle usingGLOBAL os system torch.export.load()βdeserialize_torch_artifact()β tryweights_only=Trueβ blocked- Fallback:
weights_only=Falseβ_legacy_loadβpickle.load()β RCE
Files
| File | Purpose |
|---|---|
poc_serialize_fallback.py |
Exploit PoC β generate & test malicious .pt2 |
Reference
torch/_export/serde/serialize.py:437-440β Fallback toweights_only=Falsetorch/serialization.py:1887βpickle_module.load()executes before magic check