Joblib ModelScan Extension Routing PoC
This repository contains a minimal, harmless proof-of-concept for a Huntr Model Format Vulnerability report targeting the Joblib format.
Summary
modelscan==0.8.8 detects the provided joblib payload when the file uses the supported .joblib extension. The same joblib-serialized bytes can be stored under a generic model artifact extension such as .bin; joblib.load() still reaches the payload, but ModelScan routes the .bin file through the PyTorch scanner, rejects it as an invalid PyTorch magic number, and does not fall back to a pickle/joblib scan.
This is a scanner-routing bypass candidate, not a new joblib deserialization primitive.
Safety Boundary
The PoC payload is intentionally harmless. Loading the artifact writes a marker file:
/tmp/joblib_modelscan_marker_reached.txt
It does not access credentials, make network requests, modify sensitive paths, or delete data.
Only run this inside an isolated test environment. Joblib and pickle-style formats can execute code when loaded.
Files
joblib_probe.py: builds and verifies the PoC artifacts.artifacts/joblib_marker_probe.joblib: supported-extension artifact that ModelScan flags.artifacts/joblib_marker_probe.bin: same joblib payload under a generic extension that ModelScan skips/misroutes.artifacts/modelscan_supported_joblib_receipt.txt: local receipt for.joblibdetection.artifacts/modelscan_bin_extension_show_skipped_receipt.txt: local receipt for.binskip/misroute.
Reproduce
python3.11 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
python joblib_probe.py
modelscan -p artifacts/joblib_marker_probe.joblib
modelscan -p artifacts/joblib_marker_probe.bin --show-skipped
Expected behavior:
joblib.load("artifacts/joblib_marker_probe.joblib")writes the harmless marker file.joblib.load("artifacts/joblib_marker_probe.bin")writes the same harmless marker file.- ModelScan reports the unsafe operator for
.joblib. - ModelScan reports no issue for
.binand lists it as skipped during PyTorch scanning due to invalid magic.
Versions Used
- Python 3.11
joblib==1.5.3modelscan==0.8.8