
Скрипт проверки безопасности аутентификации Milvus: CVE-2025-64513 (бэкдор sourceid) / CVE-2026-26190 (слабый токен /expr) / внутренний порт 53100
Milvus скрипт проверки безопасности аутентификации. Обнаруживает три дефекта аутентификации:
| Уязвимость | CVE | Затронутые версии | Способ обнаружения |
|---|---|---|---|
| бэкдор sourceid обходит аутентификацию | CVE-2025-64513 | < 2.4.24 / < 2.5.21 / < 2.6.5 | gRPC ListDatabases + инъекция sourceid |
| Слабый токен /expr на порту управления | CVE-2026-26190 | < 2.5.27 / < 2.6.10 | HTTP /expr?code=1%2B1&auth=by-dev (параметр code требует URL-кодирования) |
| Внутренний порт rootcoord 53100 без аутентификации | — | < 2.6.10 (начиная с 2.6.10 не прослушивается) | прямое подключение gRPC к RootCoordService |
# проверка уровня proxy (бэкдор sourceid + слабый токен /expr)
python3 milvus-auth-audit.py --host 127.0.0.1 --port 19530 --mgmt-port 9091
# полная проверка (включая внутренний порт, требуется доступность из сети контейнеров)
python3 milvus-auth-audit.py --host <IP-контейнера> --port 19530 --mgmt-port 9091 --internal-port 53100
Параметры:
--host: адрес Milvus proxy--port: gRPC-порт proxy (по умолчанию 19530)--mgmt-port: порт управления (по умолчанию 9091, здесь находится /expr)--internal-port: внутренний порт (rootcoord по умолчанию 53100, передайте 0 для пропуска)--cve-check: выводит информацию о затронутых версиях CVEpip install grpcio protobuf
Для gRPC-вызовов требуется сгенерированный из proto-определений Python-код (milvus_pb2_grpc.py, root_coord_pb2_grpc.py и т.д.), размещённый в поддиректории proto/ рядом со скриптом. Способ генерации:
# 1. Клонируйте репозиторий milvus-proto
git clone https://github.com/milvus-io/milvus-proto.git
# 2. Клонируйте исходники milvus (внутренние proto: root_coord.proto / internal.proto / proxy.proto и т.д.)
git clone https://github.com/milvus-io/milvus.git
# 3. Генерация (внутренние proto milvus находятся в milvus/pkg/proto/)
pip install grpcio-tools
python3 -m grpc_tools.protoc -I milvus-proto/proto -I milvus/pkg/proto \
--python_out=proto --grpc_python_out=proto \
milvus-proto/proto/milvus.proto milvus/pkg/proto/root_coord.proto \
milvus/pkg/proto/internal.proto milvus/pkg/proto/proxy.proto
=== 2.6.4 ===
[*] 目标: 172.22.0.4:19530 管理端口: 9091
[check] 认证状态: 已开启认证(authorizationEnabled=true)
[verify] sourceid 后门绕过认证, 数据库=['default'] -> HIT
[verify] /expr 任意表达式执行 (auth=by-dev) -> HIT
[exploit] 内部端口未认证, 数据库=['default'] -> HIT
[!] 发现 3 个可利用认证缺陷
=== 2.6.5 ===
[check] 认证状态: 已开启认证(authorizationEnabled=true)
[verify] sourceid 被拒绝 -> SAFE
[verify] /expr 任意表达式执行 (auth=by-dev) -> HIT
[exploit] 内部端口未认证, 数据库=['default'] -> HIT
[!] 发现 2 个可利用认证缺陷
=== 2.6.10 ===
[check] 认证状态: 已开启认证(authorizationEnabled=true)
[verify] sourceid 被拒绝 -> SAFE
[verify] /expr 已默认禁用 -> SAFE
[exploit] 端口不可达 -> SAFE
[+] 未发现认证缺陷
internal/proxy/authentication_interceptor.go функция validSourceID() проверяет header sourceId; когда значение после base64-декодирования равно @@milvus-member@@, весь блок аутентификации пропускается. Это механизм взаимного доверия внутренних компонентов (PerRPCCredentials в grpcclient/auth.go), но проверки источника нет, поэтому его можно подделать извне. Полная цепочка эксплуатации: sourceid + authorization=base64("root:поддельный пароль") = полный admin (proxy пропускает проверку, поддельная личность передаётся без изменений)./expr на порту управления 9091; токен аутентификации берётся из etcd.rootPath (по умолчанию by-dev), полностью предсказуем, позволяет выполнять произвольные выражения expr-lang. Начиная с 2.6.10 управляется параметром common.security.exprEnabled, по умолчанию отключён.AuthenticationInterceptor регистрируется только на proxy (19530), внутренний gRPC-сервер rootcoord (53100) работает без аутентификации. Неаутентифицированное прямое подключение внутри сети контейнеров даёт полный admin. Начиная с 2.6.10 этот порт больше не прослушивается.Только для проверки безопасности в авторизованных средах. Не используйте на неавторизованных системах.