Downloads · 30 days
0
thesecguy/poc-joblib-modelscan-bypass
poc-joblib-modelscan-bypass is a machine learning model from thesecguy. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
This repo hosts a proof-of-concept malicious joblib artifact for a disclosure to the huntr.com Model File Vulnerability program.
Downloads · 30 days
0
Access
Public
Updated Apr 30, 2026
Repo size
296 B
Likes
0
Public
Click a slice to open those files.
.md1.7 KB · 48%
From the Hugging Face model README
This repo hosts a proof-of-concept malicious joblib artifact for a disclosure to
the huntr.com Model File Vulnerability program.
Do not load this file in production. It is a real ACE payload, kept benign
(writes a sentinel file /tmp/PWNED_BY_JOBLIB_PoC).
joblib.dump(obj, "x.joblib", compress=3) writes a zlib-compressed pickle. The
zlib magic byte (0x78) at offset 0 is not a valid pickle opcode, so
pickletools.genops -- which is what ProtectAI modelscan uses to walk
opcodes -- aborts early with a parsing error and reports "No issues found".
The actual payload survives because joblib.load(...) decompresses first, then
unpickles, so the RCE constructor (__reduce__) fires.
pip install joblib==1.5.3 modelscan==0.8.8
# 1) modelscan should incorrectly mark this as clean
modelscan -p iris_classifier.joblib
# ... No issues found! ...
# ... Parsing error: at position 0, opcode b'x' unknown
# 2) joblib.load runs the embedded payload
python3 -c "import joblib; joblib.load('iris_classifier.joblib')"
ls -la /tmp/PWNED_BY_JOBLIB_PoC
The same trick works with compress=('lzma',3), ('gzip',3), ('bz2',3),
('xz',3) and the default compress=9 -- every joblib compression mode bypasses
the pickle scanner, while raw .pkl and uncompressed .joblib are correctly
flagged.
protectai/modelscan (PyPI 0.8.8 -- latest at 2026-04-30)Reported via huntr.com.