Aug 17, 2026·7 min read·2 visits
An authorization bypass vulnerability in MLflow's basic-auth middleware allows authenticated users to inject arbitrary dataset records into other users' runs without UPDATE permissions.
This technical report details a missing authorization vulnerability (CVE-2026-69146 / GHSA-3p64-6gvh-82v5) affecting the MLflow platform from version 3.13.0 to 3.15.0. When MLflow is configured with the built-in basic-auth plugin, authenticated users can bypass run-level UPDATE authorization checks, enabling unauthorized dataset and model lineage metadata injection.
MLflow is an open-source platform designed to orchestrate machine learning lifecycles, managing experiments, runs, and model deployment pipelines. Within distributed enterprise environments, MLflow implements basic authentication to partition access control, ensuring that only authorized users can read or write to target runs and datasets. The tracking server exposes a suite of API endpoints to log metrics, parameters, and artifact lineages, relying on internal middleware checks to enforce proper access barriers.
The vulnerability designated as CVE-2026-69146 lies in the authentication and authorization middleware component under mlflow/server/auth. Specifically, the system omits authorization verification when handling tracking operations for certain newly introduced API endpoints. This flaw belongs to the Missing Authorization class defined by CWE-862, where an actor can perform actions that should otherwise require higher permission tiers.
The omission permits any authenticated user to interact with the runs of other platform users, specifically injecting arbitrary data inputs into their active metadata pipelines. This bypass degrades the integrity of the ML model tracking database, creating security exposures in downstream workflows that rely on lineage telemetry. The flaw operates across network vectors, requiring no human interaction from the targeted user.
The structural flaw is located in the fail-open design of MLflow's tracking server request interceptor. When an HTTP request reaches the server, a custom authorization hook (_before_request) intercepts the request to evaluate credentials. The middleware extracts the Protobuf request class mapped to the HTTP route and attempts to retrieve a corresponding validator callback from the global BEFORE_REQUEST_HANDLERS dictionary.
If the incoming request class does not exist within the BEFORE_REQUEST_HANDLERS dictionary, the registration check returns a null value. Instead of raising an exception or denying access when a lookup fails, the interceptor defaults to allowing the transaction. This implementation choice creates a security model that fails open when new routes are introduced without explicit security registration.
Between versions 3.13.0 and 3.14.3, MLflow introduced the LogInputs and LogOutputs Protobuf classes to facilitate the tracking of dataset-level lineage metrics. Developers did not register these two classes in the initialization module of the server authentication package. Consequently, any request targeted at these endpoints bypassed the validator execution flow entirely, transitioning directly to backend database write operations.
The remediation of this vulnerability requires registering the omitted Protobuf request classes within the authentication registry. Prior to the patch, the file mlflow/server/auth/__init__.py lacked the imports for LogInputs and LogOutputs, preventing them from being mapped to their corresponding protection rules. Without these imports, the mapping registry failed to invoke the necessary verification handler for these commands.
Below is the annotated representation of the patch introduced in PR #24291, showing the inclusion of the target classes and their explicit registration into the request interceptor structure:
# Patch applied to mlflow/server/auth/__init__.py
@@ -168,9 +168,11 @@
ListScorerVersions,
ListWorkspaces,
LogBatch,
+ # Import the omitted dataset lineage input logging request class
+ LogInputs,
LogLoggedModelParamsRequest,
LogMetric,
LogModel,
+ # Import the omitted dataset lineage output logging request class
+ LogOutputs,
LogParam,
QueryTraceMetrics,
RegisterScorer,
@@ -2461,7 +2463,9 @@ def filter_list_review_queues(resp: Response) -> None:
UpdateRun: validate_can_update_run,
LogMetric: validate_can_update_run,
LogBatch: validate_can_update_run,
+ # Map LogInputs to the run update validation routine
+ LogInputs: validate_can_update_run,
LogModel: validate_can_update_run,
+ # Map LogOutputs to the run update validation routine
+ LogOutputs: validate_can_update_run,
SetTag: validate_can_update_run,
DeleteTag: validate_can_update_run,
LogParam: validate_can_update_run,This registration directly resolves the security issue by mapping the incoming commands to validate_can_update_run. This validation routine executes during the preprocessing stage, verifying that the authenticated user possesses EDIT privileges over the parent experiment containing the target run. The diagram below illustrates the routing logic and the interceptor pathway before and after the modification:
The implementation of the fix is robust as it leverages the pre-existing authorization context used for other run modifications. This minimizes the risk of regression or introducing logical loopholes during validation. However, the architectural reliance on an opt-in registration dictionary highlights a recurring vulnerability vector in systems where developers must manually declare every newly added endpoint to maintain security parity.
Exploitation of CVE-2026-69146 requires the attacker to have network access to the MLflow tracking server and valid, low-privileged credentials for the basic-auth mechanism. The attacker does not need administrative privileges or access keys to the victim's experiments. Because the server does not enforce checks on the resource boundaries of LogInputs and LogOutputs, the attacker only needs to obtain the unique identifier (run_id) of the target run to manipulate its recorded history.
An attacker can retrieve target identifiers through log monitoring, directory service listings, or guessing techniques if predictable UUID structures are in place. Once a run_id is acquired, the attacker transmits a structured JSON payload directly to the /api/2.0/mlflow/runs/log-inputs endpoint. This operation registers unauthorized datasets into the metadata database of the target run, indicating incorrect source storage locations or altered checksums.
The following payload structure outlines the request format used to insert anomalous lineage metadata into a targeted victim run:
POST /api/2.0/mlflow/runs/log-inputs HTTP/1.1
Host: mlflow-server.internal:5000
Authorization: Basic bG93X3ByaXZfdXNlcjpwYXNzd29yZA==
Content-Type: application/json
{
"run_id": "victims_sensitive_run_uuid_here",
"datasets": [
{
"dataset": {
"name": "poisoned_dataset",
"digest": "attacker_hash_value",
"source_type": "s3",
"source": "s3://attacker-controlled-bucket/malicious_data.csv"
},
"tags": [
{
"key": "injected_by",
"value": "external_attacker"
}
]
}
]
}The testing framework included in the patch suite confirms this vulnerability state by running localized requests where two distinct authenticated identities operate independently. When running on an unpatched server, the second user can successfully modify the run metadata belonging to the first user without triggering errors. Following the application of the patch, identical requests correctly terminate with an explicit permission denied exception.
The primary impact of this vulnerability is the compromise of metadata integrity across machine learning experiments and production run histories. By injecting unauthorized dataset definitions, an attacker can falsify the audit trails that track what data was used to train specific models. This capability undermines compliance verification processes, which are critical in regulated industries such as healthcare, finance, and automotive safety.
Furthermore, automated training and deployment pipelines often ingest this lineage data to trigger retraining runs or validate model deployment criteria. If an attacker injects a malicious data source path into the tracking system, subsequent automated processes might access the untrusted storage location. This can lead to downstream compromise if the data ingestion system parses unvalidated files from an external registry.
The Common Vulnerability Scoring System (CVSS) v3.1 assigns this flaw a base score of 6.5, reflecting medium severity. The impact vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N establishes that the threat vector operates over the network with low complexity. While there is no immediate loss of system availability or data confidentiality from this exploit, the high integrity impact warrants prompt remediation.
The definitive solution to mitigate CVE-2026-69146 is upgrading the MLflow installation to version 3.15.0 or later. This release permanently maps the dataset logging endpoints to the appropriate validation functions. Deployment managers should apply this update to all tracking instances where the basic-auth plugin is active.
For environments where immediate software upgrades are not possible, administrators should deploy external access controls. Applying web application firewall rules or reverse proxy filters to block incoming traffic to /api/2.0/mlflow/runs/log-inputs and /api/2.0/mlflow/runs/log-outputs protects vulnerable servers from external exploitation. These filtering rules should remain active until the tracking server can undergo a clean package upgrade.
Security operations teams should also establish regular monitoring of tracking server logs for unexpected POST operations. Reviewing the relational associations between the initiating accounts and the experiments being updated helps identify anomalous behavior. Implementing structured audit checks on MLflow tracking backends ensures that database entries are consistent with authentic developer activities.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
MLflow mlflow | >= 3.13.0, < 3.15.0 | 3.15.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862 |
| Attack Vector | Network (AV:N) |
| CVSS | 6.5 |
| EPSS Status | Not Populated |
| Impact | High Integrity (I:H) |
| Exploit Status | POC / Test-Suite Verified |
| KEV Status | Not Listed |
The software does not perform an authorization check when an actor attempts to access a resource or perform an action.
A high-severity security vulnerability exists in 9Router, an AI router and token saver dashboard. When dashboard authentication features are disabled or left in default configurations, the application exposes administrative testing routines directly to the public internet. Unauthenticated network adversaries can exploit the OIDC configuration validation endpoint to initiate arbitrary HTTP requests, routing unauthorized traffic to local loops, adjacent container ports, and cloud resource metadata interfaces.
CVE-2026-64849 is a critical Server-Side Request Forgery (SSRF) vulnerability affecting MLflow tracking servers prior to version 3.15.0. It allows unauthenticated remote attackers to bypass outbound request destination filters using DNS rebinding or HTTP redirects. This exposure risks compromising sensitive cloud infrastructure metadata and internal microservices.
MLflow prior to version 3.15.0 fails to perform proper authorization checks when registering model versions, allowing authenticated users with access to a registered model to link and access artifacts from runs and models belonging to other users without authorization.
A high-severity Regular Expression Denial of Service (ReDoS) vulnerability in the sqlparse Python library prior to version 0.6.0 allows unauthenticated remote attackers to trigger CPU exhaustion and application denial of service via crafted SQL inputs containing unmatched dollar-quoted literals or unclosed multiline comments.
A high-severity logic inversion flaw in the uniget CLI completely bypasses Sigstore cryptographic signature verification on metadata files by default. If an attacker can poison the package metadata cache or repository, they can execute arbitrary OS commands under the privileges of the active user.
A technical analysis of CVE-2026-59903 in Netty's HTTP CORS handler, where the CorsHandler overwrites existing application Vary headers with Origin, leading to unauthorized caching of sensitive information.