Security Research: ModelScan Bypass via .joblib Format
WARNING: This repository contains a proof-of-concept for a security vulnerability. The payload is benign (creates a text file). Do NOT load the
.joblibfile unless you understand the risk.
Vulnerability Summary
ModelScan (the model scanning tool recommended by huntr/Protect AI) cannot detect malicious .joblib files. It reports SCAN_NOT_SUPPORTED and skips them entirely β producing zero detections.
The exact same malicious payload packaged as a standard .pkl file is correctly detected as CRITICAL.
| File | ModelScan Result | Issues Detected | ACE on Load? |
|---|---|---|---|
malicious_reference.pkl |
Scanned | CRITICAL: 1 | Yes |
malicious_model.joblib |
SKIPPED | 0 | Yes |
How It Works
The .joblib format (used by scikit-learn) has a two-layer deserialization architecture:
Layer 1 (Pickle): NumpyArrayWrapper metadata β scanners see this (safe)
Layer 2 (Binary): Array data as pickle stream β hidden from scanners (malicious)
When a numpy array has dtype=object, joblib serializes the array data using pickle.dump() into a binary data section. On load, pickle.load() is called on this section β executing any embedded code.
ModelScan v0.8.8 has no .joblib format handler, so it skips these files completely.
Files
| File | Description |
|---|---|
malicious_model.joblib |
PoC file β benign payload (writes a text file) |
malicious_reference.pkl |
Same payload as .pkl for scanner comparison |
clean_model.joblib |
Legitimate, safe .joblib file |
verify_bypass.py |
Script to verify ModelScan bypass |
generate_poc.py |
Script that generated the PoC files |
Reproduction Steps
1. Install dependencies
pip install modelscan joblib numpy
2. Run the verification script
python verify_bypass.py
Expected output:
malicious_reference.pkl β CRITICAL: 1 issue (eval detected)
malicious_model.joblib β 0 issues (SCAN_NOT_SUPPORTED)
[CONFIRMED] SCANNER BYPASS SUCCESSFUL!
3. (Optional) Verify code execution
python verify_bypass.py --execute
This loads the .joblib file via joblib.load() and confirms that the benign payload (text file creation) executes.
Affected Components
- ModelScan 0.8.8 (latest) β
SCAN_NOT_SUPPORTEDfor.joblib - Joblib 1.5.3 (latest supported) and all versions
- scikit-learn ecosystem (models commonly saved as
.joblib)
CVSS
9.8 CRITICAL β CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE
- CWE-502: Deserialization of Untrusted Data
- CWE-693: Protection Mechanism Failure
Disclaimer
This repository is for authorized security research only, submitted as part of a responsible disclosure via huntr.com. The payload is intentionally benign.