From 4dd1cfbe293f3b179f1d97ffd8f92af4016024cb Mon Sep 17 00:00:00 2001 From: DINESH YEDDALA Date: Mon, 27 Jul 2026 10:11:48 +0000 Subject: [PATCH] testbeds:CVE-2026-0545 --- mlflow/CVE-2026-0545/Dockerfile | 20 +++++ mlflow/CVE-2026-0545/README.md | 107 ++++++++++++++++++++++++ mlflow/CVE-2026-0545/basic_auth.ini | 6 ++ mlflow/CVE-2026-0545/demo_job.py | 6 ++ mlflow/CVE-2026-0545/docker-compose.yml | 17 ++++ mlflow/CVE-2026-0545/start.sh | 20 +++++ 6 files changed, 176 insertions(+) create mode 100644 mlflow/CVE-2026-0545/Dockerfile create mode 100644 mlflow/CVE-2026-0545/README.md create mode 100644 mlflow/CVE-2026-0545/basic_auth.ini create mode 100644 mlflow/CVE-2026-0545/demo_job.py create mode 100644 mlflow/CVE-2026-0545/docker-compose.yml create mode 100644 mlflow/CVE-2026-0545/start.sh diff --git a/mlflow/CVE-2026-0545/Dockerfile b/mlflow/CVE-2026-0545/Dockerfile new file mode 100644 index 00000000..9dca4b90 --- /dev/null +++ b/mlflow/CVE-2026-0545/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.10-slim + +WORKDIR /app + +# Install a vulnerable version of MLflow (3.9.0 or earlier) +RUN pip install "mlflow[auth]==3.9.0" uvicorn + +# Copy necessary configuration and code +COPY basic_auth.ini /app/ +COPY demo_job.py /app/ +COPY start.sh /app/ + +# Make the start script executable +RUN chmod +x /app/start.sh + +# Expose the MLflow server port +EXPOSE 5590 + +# Start the MLflow server via the wrapper script +CMD ["/app/start.sh"] diff --git a/mlflow/CVE-2026-0545/README.md b/mlflow/CVE-2026-0545/README.md new file mode 100644 index 00000000..e2e2db8d --- /dev/null +++ b/mlflow/CVE-2026-0545/README.md @@ -0,0 +1,107 @@ +# CVE-2026-0545: MLflow Basic Auth Bypass & Unauthenticated Job Execution + +MLflow contains an access control vulnerability in its job execution subsystem (`MLFLOW_SERVER_ENABLE_JOB_EXECUTION`). When job execution is enabled alongside basic authentication on MLflow servers, authorization checks fail to properly restrict unauthenticated or low-privileged HTTP requests to job management endpoints (e.g., `/ajax-api/3.0/jobs/`). This weakness allows unauthorized users to trigger pre-configured job functions and execute underlying commands within the server container context. + +--- + +## Overview + +| Attribute | Details | +| :--- | :--- | +| **CVE ID** | CVE-2026-0545 | +| **Vulnerability Type** | Incorrect Authorization / Improper Access Control (CWE-284) | +| **Vulnerable Versions** | `mlflow[auth] <= 3.9.0` | +| **Patched / Fixed Versions** | `mlflow[auth] >= 3.9.1` | +| **Impact** | Remote Code Execution / Unauthorized Job Execution | + +--- + +## Environment Setup + +To deploy the vulnerable environment for testing or verification in an isolated laboratory context, use the following deployment configuration files. + +### Configuration Files + +#### `basic_auth.ini` +```ini +[mlflow] +default_permission = NO_PERMISSIONS +database_uri = sqlite:///basic_auth.db +admin_username = admin +admin_password = password1234 +authorization_function = mlflow.server.auth:authenticate_request_basic_auth +``` + +#### `demo_job.py` +```python +from mlflow.server.jobs import job +import subprocess + +@job(name="run_task", max_workers=1) +def run_task(command="id"): + return subprocess.check_output(command, shell=True).decode() +``` + +#### `start.sh` +```bash +#!/bin/bash + +# Configuration for MLflow Basic Auth +export MLFLOW_AUTH_CONFIG_PATH=/app/basic_auth.ini +export MLFLOW_FLASK_SERVER_SECRET_KEY=test-secret-key + +# Enable vulnerable job execution settings +export MLFLOW_SERVER_ENABLE_JOB_EXECUTION=true +export _MLFLOW_SUPPORTED_JOB_FUNCTION_LIST=demo_job.run_task +export _MLFLOW_ALLOWED_JOB_NAME_LIST=run_task +export PYTHONPATH=/app + +mkdir -p /app/artifacts + +exec mlflow server \ + --app-name=basic-auth \ + --host 0.0.0.0 \ + --port 5590 \ + --backend-store-uri sqlite:///backend.db \ + --default-artifact-root /app/artifacts +``` + +#### `Dockerfile` +```dockerfile +FROM python:3.10-slim + +WORKDIR /app + +# Install vulnerable MLflow version +RUN pip install "mlflow[auth]==3.9.0" uvicorn + +COPY basic_auth.ini /app/ +COPY demo_job.py /app/ +COPY start.sh /app/ + +RUN chmod +x /app/start.sh + +EXPOSE 5590 + +CMD ["/app/start.sh"] +``` + +#### `docker-compose.yml` +```yaml +version: '3.8' + +services: + mlflow-server: + build: + context: . + dockerfile: Dockerfile + container_name: mlflow_app + ports: + - "5590:5590" + volumes: + - mlflow_data:/app/artifacts + restart: unless-stopped + +volumes: + mlflow_data: +``` diff --git a/mlflow/CVE-2026-0545/basic_auth.ini b/mlflow/CVE-2026-0545/basic_auth.ini new file mode 100644 index 00000000..29ef67b6 --- /dev/null +++ b/mlflow/CVE-2026-0545/basic_auth.ini @@ -0,0 +1,6 @@ +[mlflow] +default_permission = NO_PERMISSIONS +database_uri = sqlite:///basic_auth.db +admin_username = admin +admin_password = password1234 +authorization_function = mlflow.server.auth:authenticate_request_basic_auth diff --git a/mlflow/CVE-2026-0545/demo_job.py b/mlflow/CVE-2026-0545/demo_job.py new file mode 100644 index 00000000..821b03c3 --- /dev/null +++ b/mlflow/CVE-2026-0545/demo_job.py @@ -0,0 +1,6 @@ +from mlflow.server.jobs import job +import subprocess + +@job(name="run_task", max_workers=1) +def run_task(command="id"): + return subprocess.check_output(command, shell=True).decode() diff --git a/mlflow/CVE-2026-0545/docker-compose.yml b/mlflow/CVE-2026-0545/docker-compose.yml new file mode 100644 index 00000000..47a50aa8 --- /dev/null +++ b/mlflow/CVE-2026-0545/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + mlflow-server: + build: + context: . + dockerfile: Dockerfile + container_name: mlflow_app + ports: + - "5590:5590" + volumes: + # Only keep the persistent data storage mount + - mlflow_data:/app/artifacts + restart: unless-stopped + +volumes: + mlflow_data: diff --git a/mlflow/CVE-2026-0545/start.sh b/mlflow/CVE-2026-0545/start.sh new file mode 100644 index 00000000..46203a9e --- /dev/null +++ b/mlflow/CVE-2026-0545/start.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Configuration for MLflow Basic Auth +export MLFLOW_AUTH_CONFIG_PATH=/app/basic_auth.ini +export MLFLOW_FLASK_SERVER_SECRET_KEY=test-secret-key + +# Requirements to trigger the bypass +export MLFLOW_SERVER_ENABLE_JOB_EXECUTION=true +export _MLFLOW_SUPPORTED_JOB_FUNCTION_LIST=demo_job.run_task +export _MLFLOW_ALLOWED_JOB_NAME_LIST=run_task +export PYTHONPATH=/app + +mkdir -p /app/artifacts + +exec mlflow server \ + --app-name=basic-auth \ + --host 0.0.0.0 \ + --port 5590 \ + --backend-store-uri sqlite:///backend.db \ + --default-artifact-root /app/artifacts