MLflow Issue Management API BOLA/IDOR Proof-of-Concept

IMPORTANT NOTE: For a comprehensive technical analysis, root cause breakdown, and remediation guidelines, please refer to the Report.md file included in this repository. This README serves primarily as an execution guide for the Proof-of-Concept (PoC).

Overview

This repository demonstrates a High-severity Broken Object Level Authorization (BOLA) / Insecure Direct Object Reference (IDOR) vulnerability in the Issue Management API of MLflow version 3.12.0.

When the basic-auth plugin is enabled, the API fails to validate ownership permissions for Issue objects. This architectural flaw allows any authenticated user to enumerate, read, and modify issues created by other users, bypassing intended project isolation mechanisms.


Vulnerability Summary

  • Type: Broken Object Level Authorization (BOLA) / IDOR (CWE-639)
  • Library: MLflow (Issue Management API v3)
  • Impact: Unauthorized read and modification of confidential project tracking data.
  • Root Cause: Absence of authorization logic across routing, service, and database layers; failure to filter SQLAlchemy queries by the created_by parameter or current user context.

Attack Scenario

In environments relying on MLflow's native authentication:

  1. Enumeration: An attacker queries the /api/3.0/mlflow/issues/search endpoint using a known experiment_id to extract deterministic issue_id values belonging to the victim.
  2. Unauthorized Read: The attacker sends a GET request to /api/3.0/mlflow/issues/<issue_id>, successfully retrieving the victim's confidential issue metadata.
  3. Unauthorized Modification: The attacker submits a PATCH request to the same endpoint, successfully overwriting the victim's issue data (e.g., name, description, status) without ownership verification.

Repository Structure

mlflow-bola-poc/
β”œβ”€β”€ Report.md             # Full vulnerability analysis, root cause, and remediation
β”œβ”€β”€ mlflow_bola_poc.py    # Core exploit script with API request sequences
β”œβ”€β”€ auth.ini              # Dynamic configuration for MLflow basic-auth isolation
β”œβ”€β”€ requirements.txt      # Dependency specification file
β”œβ”€β”€ setup_and_run.sh      # Automated bash script to initialize venv and run PoC
└── README.md             # This execution guide

Reproduction Steps

1. Execute the Automated Setup Script

Ensure you are in a Unix-like environment (Linux/macOS) with Python 3 installed. Run the bash script to isolate the environment and execute the exploit payload:

chmod +x setup_and_run.sh
bash setup_and_run.sh

2. Observe the Execution Flow

The script dynamically instantiates a local MLflow 3.12.0 server instance on 127.0.0.1:5000 with the basic-auth plugin enabled. It provisions two users: User A (Victim) and User B (Attacker).

The expected terminal output will validate the exploit sequence:

[STEP 8] ATTACK #1: User B reads Alice's issue (V3 API)...
[!] BOLA CONFIRMED: User B reading data from User A!

[STEP 9] ATTACK #2: User B modifies Alice's issue (V3 API)...
[!] BOLA CONFIRMED: User B modifies data from User A!

[STEP 10] ATTACK #3: User B searches all issues (ENUMERATION/V3 API)...
[!] BOLA CONFIRMED: User B listed 1 issue(s) combine issue_id secret of User A!

The script automatically terminates the MLflow server process and purges the temporary SQLite databases to maintain a clean system state.


Security Impact

  • Confidentiality: Attackers can extract sensitive operational data, internal architectural discussions, or vulnerability notes logged within the MLflow tracking environment.
  • Integrity: Attackers can alter issue statuses, overwrite descriptions, or manipulate metadata, compromising the reliability of project management artifacts within MLflow.

Affected Components

  • API Endpoints: /api/2.0/mlflow/issues/* and /api/3.0/mlflow/issues/*
  • Controller Layer: mlflow.server.handlers
  • Storage Layer: mlflow.store.tracking.sqlalchemy_store.SqlAlchemyStore
  • Plugin Integration: MLflow basic-auth plugin.

Mitigation

  • Enforce Authorization Context: Implement authentication verification (e.g., @require_login) on all issue-related HTTP handlers and inject the user identity into the underlying store methods.
  • Implement Query-Level Filtering: Modify SQLAlchemy queries to enforce ownership via .filter(SqlIssue.created_by == current_user_id).
  • Structural Access Control: Implement a permission matrix linking user_id to experiment_id to validate read/write permissions at the workspace level.

Author

Nguyen Duc Canh (canhnguyen26)


Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support