
Script de detecção de segurança de autenticação do Milvus: CVE-2025-64513 (backdoor sourceid) / CVE-2026-26190 (token fraco /expr) / porta interna 53100
Script de auditoria de segurança de autenticação do Milvus. Detecta três falhas de autenticação:
| Falha | CVE | Versões afetadas | Método de detecção |
|---|---|---|---|
| Backdoor sourceid que contorna a autenticação | CVE-2025-64513 | < 2.4.24 / < 2.5.21 / < 2.6.5 | Injeção de sourceid via gRPC ListDatabases |
| Token fraco /expr na porta de gerenciamento | CVE-2026-26190 | < 2.5.27 / < 2.6.10 | HTTP /expr?code=1%2B1&auth=by-dev (o parâmetro code requer codificação de URL) |
| Porta interna rootcoord 53100 sem autenticação | — | < 2.6.10 (a partir da 2.6.10, não escuta mais) | Conexão gRPC direta ao RootCoordService |
# detecção na camada do proxy (backdoor sourceid + token fraco do /expr)
python3 milvus-auth-audit.py --host 127.0.0.1 --port 19530 --mgmt-port 9091
# detecção completa (inclui a porta interna; requer acesso na rede do contêiner)
python3 milvus-auth-audit.py --host <IP-do-contêiner> --port 19530 --mgmt-port 9091 --internal-port 53100
Parâmetros:
--host: endereço do proxy Milvus--port: porta gRPC do proxy (padrão 19530)--mgmt-port: porta de gerenciamento (padrão 9091; /expr fica aqui)--internal-port: porta interna (padrão do rootcoord: 53100; passe 0 para ignorar)--cve-check: imprime as descrições das versões afetadas pelos CVEspip install grpcio protobuf
As chamadas gRPC exigem o código Python gerado a partir das definições de proto (milvus_pb2_grpc.py, root_coord_pb2_grpc.py, etc.), colocado no subdiretório proto/, no mesmo diretório do script. Como gerar:
# 1. clonar o repositório milvus-proto
git clone https://github.com/milvus-io/milvus-proto.git
# 2. clonar o código-fonte do milvus (protos internos: root_coord.proto / internal.proto / proxy.proto etc.)
git clone https://github.com/milvus-io/milvus.git
# 3. gerar (os protos internos do milvus ficam em 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 ===
[*] Alvo: 172.22.0.4:19530 Porta de gerenciamento: 9091
[check] Status da autenticação: autenticação habilitada(authorizationEnabled=true)
[verify] backdoor sourceid contornou a autenticação, banco de dados=['default'] -> HIT
[verify] execução de expressão arbitrária no /expr (auth=by-dev) -> HIT
[exploit] porta interna sem autenticação, banco de dados=['default'] -> HIT
[!] 3 falhas de autenticação exploráveis encontradas
=== 2.6.5 ===
[check] Status da autenticação: autenticação habilitada(authorizationEnabled=true)
[verify] sourceid rejeitado -> SAFE
[verify] execução de expressão arbitrária no /expr (auth=by-dev) -> HIT
[exploit] porta interna sem autenticação, banco de dados=['default'] -> HIT
[!] 2 falhas de autenticação exploráveis encontradas
=== 2.6.10 ===
[check] Status da autenticação: autenticação habilitada(authorizationEnabled=true)
[verify] sourceid rejeitado -> SAFE
[verify] /expr desabilitado por padrão -> SAFE
[exploit] porta inacessível -> SAFE
[+] Nenhuma falha de autenticação encontrada
internal/proxy/authentication_interceptor.go, a função validSourceID() verifica o header sourceId; quando o valor decodificado em base64 é igual a @@milvus-member@@, todo o ramo de autenticação é ignorado. Esse é o mecanismo de confiança mútua entre componentes internos (PerRPCCredentials em grpcclient/auth.go), mas não há validação de origem, permitindo falsificação externa. Cadeia de exploração completa: sourceid + authorization=base64("root:senha falsa") = full admin (o proxy ignora a validação e repassa a identidade falsa como está)./expr, na porta de gerenciamento 9091, usa um token de autenticação derivado de etcd.rootPath (padrão by-dev), totalmente previsível, permitindo executar expressões arbitrárias em expr-lang. A partir da 2.6.10, é controlado por common.security.exprEnabled e fica desabilitado por padrão.AuthenticationInterceptor é registrado apenas no proxy (19530); o servidor gRPC interno do rootcoord (53100) não tem autenticação. Uma conexão direta sem autenticação dentro da rede do contêiner já concede full admin. A partir da 2.6.10, essa porta deixa de escutar.Destinado apenas à verificação de segurança em ambientes autorizados. Não use em sistemas não autorizados.