Statically scan Python pickles and ML model files for code-execution risks - without ever loading them. A browser port of picklescan. Files never leave your device.
Upload a model or pickle file
.pkl .pickle .pt .pth .ckpt .bin .joblib .npy .npz .zip .safetensors
GLOBAL / STACK_GLOBAL imports - it never executes the file.REDUCE call sites, embedded executables, and Zip-Slip / executable archive members.safetensors.Statically scan Python pickle and ML model files (PyTorch, NumPy, joblib) for code-execution risks. A browser port of picklescan - files never leave your device.
Python's pickle format can run arbitrary code when a file is loaded, which makes untrusted ML model weights a real supply-chain risk. A malicious pickle imports a dangerous function (like os.system or builtins.eval) and calls it during deserialization. This tool is a browser-based port of the well-known picklescan project. It disassembles the pickle opcode stream and reports every imported symbol, flagging the dangerous ones - all without ever executing the file, and without uploading it anywhere. Note: this is a heuristic scanner. A clean result is not a guarantee of safety.
Input:
model.pt (PyTorch archive) or weights.pkl
Output:
DANGEROUS - archive/data.pkl imports os.system
Does scanning a malicious pickle put me at risk?
No. The scanner only walks the pickle's opcode bytecode to read its imports - it never calls pickle.load or executes any opcode. Everything runs locally in your browser.
Which file types are supported?
Raw pickles (.pkl, .pickle, .joblib, .dat, .data), PyTorch/zip archives (.pt, .pth, .ckpt, .bin, .zip, .npz), and NumPy .npy files. .safetensors is recognized as a safe, non-executable format. 7z archives are not parsed in-browser.
What does a 'dangerous' result mean?
The pickle imports a symbol on picklescan's denylist - modules like os, subprocess, sys, or functions like builtins.eval/exec - which can be abused to run code on load. Do not load such a file with a trusting loader.
Is a 'safe' result a guarantee?
No. This is a heuristic scanner based on a known-bad denylist plus pattern checks; it can miss novel or obfuscated gadgets. For untrusted models, prefer the safetensors format, which cannot execute code.
Why does it say 'suspicious'?
An import was found that isn't on the denylist but couldn't be fully resolved (for example, a dynamically constructed module/name), or a heuristic finding fired - such as a base64 blob, an embedded URL/IP, or an opcode pattern that warrants manual review.
What are 'heuristic findings'?
Beyond the import denylist, the scanner looks for evasion and embedded threats: payloads hidden in string operands (exec/eval, getattr obfuscation, base64, shell commands, URLs/IPs), the actual REDUCE call sites, embedded native executables (PE/ELF/Mach-O), and dangerous archive members (Zip-Slip path traversal, .exe/.sh/.dll). These catch attacks that don't directly import an obviously-bad module.