ModelScan v0.8.8 legacy PyTorch multi-pickle scan bypass
Proof-of-concept legacy .pt file demonstrating that ModelScan's PyTorch scanner only inspects the first pickle record. Malicious globals in any record after the first (e.g., in the object_graph record at index 3) bypass detection and execute under torch.load(weights_only=False).
This file is intentionally malicious for demonstration purposes. Do not load it on a system you care about. The payload writes a marker file R3_marker.txt containing the timestamp of execution.
See the huntr submission for the detailed Description.
Git LFS note
The PoC file R3_v2_legacy_object_graph_exec.pt is stored via Git LFS. To fetch the actual 467-byte fixture (not the pointer):
git lfs install
git clone https://huggingface.co/askeladd-k/modelscan-legacy-pt-bypass poc
cd poc
git lfs pull
Or download R3_v2_legacy_object_graph_exec.pt directly from the HF repo's Files tab.
Prerequisites
Tested with modelscan==0.8.8 and torch>=1.6. If torch>=2.6, the reproduction requires either:
TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD=1set in the environment, ORweights_only=Falsepassed explicitly totorch.load(...).
This is because PyTorch 2.6.0 (2025-01-29) changed the default to weights_only=True, which blocks the malicious __builtin__ exec global. The submission's claim is precisely that ModelScan misses the malicious record AND the loader (in the unsafe configuration) executes it.
Reproduction
python -m venv venv
# Windows: . venv/Scripts/activate
# POSIX: . venv/bin/activate
pip install modelscan==0.8.8 torch
python repro.py
Expected output
[build] wrote R3_v2_legacy_object_graph_exec.pt (467 bytes)
[scan] modelscan total_issues=0 (BYPASS confirmed)
[load] torch.load executed payload: R3_POC_EXECUTED marker present
AI disclosure
This proof-of-concept was generated with AI-assisted analysis and manually verified in a clean environment. The fixture build script (build_poc.py) and the reproduction script (repro.py) are included for full transparency.