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 .joblib file 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_SUPPORTED for .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.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support