VORVEXAPEX

CVE-2025-62593: um anúncio malicioso executando comando no seu cluster de IA

O serviço estava em 127.0.0.1, sem porta aberta para a internet, e mesmo assim um site qualquer conseguiu mandar comando para ele. A checagem de segurança que falhou cabia em uma linha de código.

Por Equipe VorvexPublicado em 20 de agosto de 20267 min de leitura

Quase todo inventário de superfície de ataque começa pela mesma pergunta: o que está exposto na internet? É a pergunta certa, e ela deixa de fora exatamente o tipo de falha que a CISA adicionou ao catálogo Known Exploited Vulnerabilities em 17 de agosto de 2026. A CVE-2025-62593 afeta o Ray, framework de computação distribuída usado para treinar e servir modelos de IA, e não precisa de nenhuma porta aberta para o mundo. Ela precisa que o desenvolvedor abra uma aba do navegador.

Diagram showing a developer laptop with an open browser on one side and a malicious web server on the other, with a local machine learning dashboard bound to the loopback address inside the laptop. Arrows show the attacker domain first resolving to the attacker public IP address and then re-resolving to the loopback address, so the browser request lands on the local dashboard.
No DNS rebinding, o nome do domínio continua o mesmo para o navegador, mas passa a apontar para dentro da própria máquina da vítima.

A falha em uma frase

A CVE-2025-62593 é uma injeção de código (CWE-94, combinada com CWE-352, falsificação de requisição entre sites) que permite a um site malicioso enviar requisições autenticadas ao painel e à API do Ray que rodam na máquina do desenvolvedor, chegando à execução de comandos arbitrários. A NVD atribui CVSS 4.0 de 9,4, crítico, com o vetor CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H, e CVSS 3.1 de 8,8, alto, com CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H. A diferença entre as duas notas é justamente a interação do usuário, que na prática significa clicar em um link ou ver um anúncio.

  • Afetadas: todas as versões do Ray anteriores à 2.52.0
  • Corrigida em: Ray 2.52.0
  • Endpoints vulneráveis: /api/jobs/ e /api/job_agent/jobs/, na porta padrão 8265 do painel
  • Navegadores que permitem o ataque: Firefox e Safari; o Chrome escapa por um bug de implementação da própria fetch API
  • Publicada na NVD em 26 de novembro de 2025, adicionada ao CISA KEV em 17 de agosto de 2026

A falha foi encontrada por avilum, da Oligo, e reportada com prova de conceito por JLLeitschuh, da Socket. O crédito importa aqui porque a correção não foi apenas um remendo pontual: a versão 2.52.0 também introduziu autenticação por token no painel, um recurso que até então não existia. Vale reparar que essa autenticação vem desabilitada por padrão, então atualizar não é o passo final, é o primeiro.

A defesa que não era defesa: checar o User-Agent

O Ray sabia que requisições vindas de navegador eram perigosas para uma API que executa código. A proteção implementada foi verificar se o cabeçalho User-Agent da requisição começava com a palavra Mozilla, partindo da ideia de que só navegador manda esse valor e que navegador não consegue mudá-lo.

python
# Ray < 2.52.0: a unica barreira contra requisicao vinda de navegador.
def is_browser_request(req: Request) -> bool:
    """Checks if a request is made by a browser like user agent."""
    return req.headers["User-Agent"].startswith("Mozilla")

# A premissa: um navegador nao consegue alterar o proprio User-Agent.
# Falsa no Firefox e no Safari, onde a fetch API aceita definir o header.
# No Chrome, um bug de implementacao acabou impedindo a alteracao,
# ou seja, a protecao so funciona por acidente, em um navegador so.
A verificação inteira cabe em uma linha, e a premissa por trás dela é falsa em dois dos três navegadores mais usados.

A segunda metade da premissa é que existe uma lista de cabeçalhos que o JavaScript de uma página não pode definir, os chamados forbidden headers. O User-Agent esteve nessa lista por muito tempo, e saiu. Firefox e Safari implementam a especificação atual e permitem definir o User-Agent em uma chamada fetch. O Chrome ainda bloqueia, mas por um defeito de implementação, não por decisão de segurança. Uma proteção que depende de um bug alheio para continuar valendo não é uma proteção, é uma janela de tempo.

DNS rebinding: o navegador como ponte para dentro da rede

Furar a checagem de User-Agent não basta sozinho, porque a política de mesma origem do navegador impede que o JavaScript de um site leia a resposta de outro domínio. O DNS rebinding existe justamente para contornar isso: em vez de tentar acessar outro domínio, o atacante mantém o mesmo nome e troca o endereço IP para o qual ele resolve.

text
# Sequencia de um DNS rebinding, do ponto de vista do navegador.

1) A vitima abre https://site-do-atacante.exemplo
   DNS: site-do-atacante.exemplo -> 203.0.113.10   (TTL de 1 segundo)

2) A pagina carrega e o JavaScript apenas espera o TTL expirar.

3) O navegador resolve o MESMO nome de novo:
   DNS: site-do-atacante.exemplo -> 127.0.0.1

4) fetch("http://site-do-atacante.exemplo:8265/api/jobs/", { ... })
   Para a politica de mesma origem, continua sendo a mesma origem.
   Para a pilha de rede, o pacote agora vai para o servico local.
O nome do domínio nunca muda, então o navegador considera tudo a mesma origem. O que muda é para onde esse nome aponta.

O resultado é que o navegador da vítima passa a agir como um cliente HTTP dentro da rede confiável, obedecendo a um script controlado pelo atacante. Isso vale para o Ray na porta 8265, mas vale igualmente para qualquer painel administrativo, roteador doméstico, banco de dados em desenvolvimento ou API interna que confie no fato de estar escutando apenas no loopback ou na rede local. O loopback nunca foi um limite de confiança do ponto de vista do navegador.

Do /api/jobs ao comando arbitrário

Chegando aos endpoints /api/jobs/ e /api/job_agent/jobs/, o resto é o funcionamento normal do produto. A API de jobs do Ray recebe um campo entrypoint com o comando a ser executado no cluster e o executa. É o que ela existe para fazer. A vulnerabilidade não está na execução, está no fato de uma página web arbitrária conseguir chegar até essa chamada.

http
POST /api/jobs/ HTTP/1.1
Host: 127.0.0.1:8265
Content-Type: application/json
User-Agent: laboratorio-interno

{"entrypoint": "id", "runtime_env": {}, "metadata": {}}

# O campo entrypoint e uma linha de comando executada no cluster.
# Aqui usamos 'id' apenas para ilustrar. O ponto do post nao e o
# comando, e o fato de essa requisicao poder partir de uma aba
# de navegador aberta em um site qualquer.
A API faz exatamente o que promete. O problema é o alcance: com o rebinding, quem monta essa requisição é o site que a vítima abriu.

Do ponto de vista de impacto, a estação de trabalho de quem desenvolve modelos costuma ser uma das máquinas mais interessantes de uma empresa. Ela tem chave de API de provedor de nuvem, token de repositório privado, credencial de data lake, acesso a GPU e, com frequência, cópia local de dados de treino. Um comando executado ali dificilmente é o objetivo final do atacante, é o ponto de partida.

RondoDox, ShadowRay 2.0 e o prazo de três dias da CISA

A linha do tempo dessa falha tem um detalhe raro. Segundo análise da Bitsight, a botnet RondoDox começou a tentar explorar a CVE-2025-62593 em 24 de novembro de 2025, dois dias antes de a vulnerabilidade ser publicada na NVD. Não é o padrão usual de engenharia reversa do patch depois do anúncio: quem operava a botnet estava acompanhando o repositório, não o boletim.

Em 17 de agosto de 2026 a CISA incluiu a falha no catálogo KEV, e sob a diretiva BOD 26-04 as agências federais americanas tiveram três dias para corrigir, com prazo em 20 de agosto de 2026. Três dias é o prazo reservado para o que já está sendo explorado de forma consistente, e é um sinal razoável de prioridade também para quem não é órgão público americano.

Vale separar essa falha de uma segunda história que envolve o mesmo produto e costuma ser confundida com ela. A campanha ShadowRay 2.0, documentada pela Oligo, explora a CVE-2023-48022, que trata de clusters Ray com a API de jobs acessível sem autenticação e expostos diretamente na internet. Essa CVE é marcada como disputada, porque a Anyscale sustenta que se trata de comportamento documentado do produto, que pressupõe execução em rede controlada. A campanha transforma clusters expostos em botnet de mineração de criptomoeda, e a Oligo relata que o número de ambientes Ray alcançáveis saltou de alguns milhares para a casa das centenas de milhares.

As duas histórias apontam para a mesma lição por caminhos opostos. Na CVE-2023-48022, o cluster está exposto e a ausência de autenticação é por design. Na CVE-2025-62593, o serviço não está exposto e ainda assim é alcançado, através do navegador. Em ambos os casos, a suposição de que a rede resolve o problema de autenticação é o que quebra.

O que muda no escopo do pentest

Illustration of a developer workstation drawn as a large box containing several small service icons bound to local ports, with a browser icon inside the same box connected by an arrow to the public internet outside the box, and a return arrow showing external instructions reaching the internal services through the browser.
Serviços que só escutam em localhost continuam alcançáveis pelo navegador que roda na mesma máquina. O navegador é a ponte que atravessa o limite de rede.

Nos escopos que chegam até nós, a estação de trabalho quase nunca entra, e os serviços locais de desenvolvimento entram ainda menos. A justificativa é sempre a mesma: não está exposto. Essa CVE é um contraexemplo direto, e não é o único. Painel de orquestração de contêiner, notebook Jupyter, servidor de documentação, ferramenta de build com API HTTP, proxy de depuração, tudo isso costuma subir em localhost sem autenticação porque parece um ambiente privado.

  • Atualize o Ray para 2.52.0 ou superior em todo lugar, inclusive nas estações de trabalho, que são o alvo direto desta falha
  • Habilite a autenticação por token do Ray, que existe a partir da 2.52.0 mas vem desligada por padrão
  • Levante os serviços que escutam em localhost nas máquinas de desenvolvimento e trate cada um como superfície alcançável pelo navegador, não como ambiente privado
  • Verifique se algum cluster Ray está acessível a partir da internet, o cenário da CVE-2023-48022 e da campanha ShadowRay 2.0, que é um problema separado e mais grave
  • Se houver suspeita de comprometimento em uma estação de desenvolvimento, rotacione chave de nuvem, token de repositório e credencial de dados antes de considerar o caso encerrado
  • Inclua explicitamente a estação de trabalho e a infraestrutura de IA no escopo do próximo pentest, não como item de apoio, e sim como alvo

Este post é educativo e voltado à defesa. Não publicamos exploit funcional: os trechos acima reproduzem código já divulgado no advisory oficial e o uso documentado da API do produto. O que queremos deixar claro é a premissa que falhou. Quando a proteção de um serviço é o endereço em que ele escuta, quem tem um navegador dentro da rede já está do lado de dentro.

← Voltar ao blog

Quer essa mesma profundidade aplicada ao seu ambiente?

Conte o que você precisa validar e a equipe monta um escopo de pentest sob medida.

Falar no WhatsApp

Pronto para avaliar o risco da sua empresa?