Uma ilustração abstrata gerada sobre um fundo azul-marinho profundo. Uma ampla estrutura de ponte em tom ardósia atravessa o quadro, e uma porta retangular em sua face esquerda está aberta e brilhando em âmbar. Por essa abertura, um fluxo de pequenos blocos idênticos jorra para fora sobre uma grade de projeto tênue, atravessando um fino limite ciano pontilhado desenhado em primeiro plano sem ser detido. No canto inferior direito, os blocos alimentam uma baixa treliça translúcida de nós conectados que lembra um armazenamento de memória. Nenhum texto, letras, números, pessoas, marcas de produtos ou logotipos de organizações aparecem. O logotipo OrcaRouter está composto no canto inferior direito de uma faixa branca abaixo da arte.
AI Safety Incidents

RufRoot: uma solicitação não autenticada para a ponte MCP do Ruflo executou comandos, roubou chaves e envenenou a memória da IA

Autor

Rowan Sterling

Data de publicação

Modelos mais recentes · 20Ver todos os modelos →
Benchmarks: Artificial Analysis · atualizado diariamente
Voltar para todas as publicações

Em 30 de junho de 2026, Noma Labs entregou ao mantenedor do Ruflo um exploit funcional contra o próprio projeto. A divisão de pesquisa da Noma Security havia descoberto que o Ruflo — uma plataforma de orquestração de agentes de código aberto, anteriormente lançada como Claude Flow — fornecia uma implantação padrão do Docker Compose que vinculava sua ponte do Model Context Protocol à porta 3001 em todas as interfaces de rede e não exigia autenticação alguma. Uma única requisição HTTP para o /mcp endpoint era suficiente para executar comandos de shell dentro do contêiner como o usuário node, e a partir desse shell um atacante poderia ler todas as chaves de API dos provedores de LLM no ambiente, extrair todas as conversas armazenadas, criar enxames de agentes cobrados nas chaves da vítima e gravar instruções no armazenamento de aprendizado AgentDB que continuaria a orientar as respostas da IA para todos os usuários daquela instância. A falha é CVE-2026-59726, apelidada de RufRoot, com pontuação CVSS 10.0 e corrigida na versão 3.16.3 em até 24 horas. Nenhuma fonte que consultamos relata que ela tenha sido explorada em ambiente real. O registro do próprio arquivo sobre essa falha, com sua lista de fontes e grau de confiança, está em o arquivo de incidentes de IA, ao lado das outras entradas de MCP e infraestrutura registradas em torno dele.

O padrão que abriu a porta

Ruflo é o que a Noma Labs chama de meta-harness de agentes: uma camada auto-hospedada para enxames de até 100 agentes, criada para Claude Code e OpenAI Codex, com memória de longo prazo e um servidor MCP integrado para chamada de ferramentas. A configuração usual é a que a Noma descreve — clone o repositório, adicione chaves de API de LLM, execute docker compose up -d. O arquivo compose padrão do projeto vinculava a bridge a 0.0.0.0 na porta 3001 e vinculava seu MongoDB associado a todas as interfaces em 27017, com a autenticação do Mongo desativada. O alcance disso depende do firewall, do grupo de segurança e da segmentação de rede em torno da implantação; a própria formulação da Noma é que qualquer instância acessível pela rede era totalmente explorável sem autenticação.

O MCP Bridge é um servidor Express.js que converte requisições JSON-RPC recebidas via HTTP em chamadas à biblioteca interna de ferramentas da Ruflo. Na linha vulnerável, essa biblioteca continha 233 ferramentas que abrangiam acesso ao shell, operações de banco de dados, gerenciamento de agentes e armazenamento de memória. A análise de Noma é direta sobre o que isso faz dele: "O MCP Bridge não é uma interface de depuração auxiliar qualquer; em vez disso, é o sistema nervoso central da Ruflo. Toda chamada de ferramenta, toda ação de agente, toda operação de memória passa pelo MCP Bridge."

A camada de autenticação estava ausente, não apenas fraca. POST /mcp e POST /mcp/:group implementam o protocolo MCP JSON-RPC e passam solicitações recebidas tools/call diretamente à função interna executeTool(). A Ruflo mantinha uma lista de bloqueio de comandos, AUTOPILOT_BLOCKED_PATTERNS, destinada a impedir operações de shell perigosas, mas o aviso do GitHub é explícito que ela "era aplicada apenas no fluxo do autopilot. POST /mcp e POST /mcp/:group a contornavam". Assim, uma única chamada não autenticada que nomeava ruflo__terminal_execute executou comandos arbitrários como o usuário node do contêiner, registrado no aviso como uid 1000, sem necessidade de token, sessão ou interação prévia. Nenhuma escalada de privilégios foi necessária para o que veio a seguir: as credenciais, as APIs dos agentes, o armazenamento de memória e o banco de dados estavam todos acessíveis a partir desse shell.

A cadeia, em oito etapas

A Noma Labs publicou uma prova de conceito em oito etapas e confirmou cada etapa ao vivo contra uma implantação padrão do Ruflo na AWS EC2, usando callbacks fora de banda para o Burp Collaborator para verificar a execução e a exfiltração. As etapas não são consequências especulativas acumuladas sobre uma falha teórica; são uma sequência demonstrada, e a seção de remediação do comunicado foi escrita para operadores que podem já estar no meio dela.

A hand-built HTML card headed 'The RufRoot chain, step by step', kicker 'RufRoot - CVE-2026-59726', subtitle 'Eight steps Noma Labs confirmed live against a default Ruflo deployment on AWS EC2'. Eight rows, each with a circled step number, the action, and what it yielded. 1, call tools/list: enumerate the 233 exposed tools. 2, call ruflo__terminal_execute over POST /mcp: shell inside the bridge container as node, uid 1000, verified by an out-of-band callback. 3, run printenv: every LLM provider API key in the container environment. 4, call ruflo__swarm_init and ruflo__agent_spawn: attacker-controlled agent swarms running on the victim's keys and compute. 5, call ruflo__agentdb_pattern-store: a fabricated SOC2 policy in the learning store, steering future output for all users. 6, query MongoDB on port 27017: every stored conversation, title and metadata. 7, write /app/beacon.js and inject it into index.js, then kill PID 1: a backdoor that survives the container restart policy. 8, clear shell history: no forensic trace. A footer cites Noma Labs and CVE-2026-59726, and marks step 5 as the step a patched redeploy does not undo.

O reconhecimento vem primeiro porque a lista de ferramentas é pública para qualquer chamador: tools/list retorna todas as 233 entradas sem credencial. A execução de comandos decorre do mesmo endpoint, e a prova de conceito de Noma confirmou isso com um callback fora de banda, em vez de uma inferência a partir do corpo de uma resposta. A etapa de ambiente é a que transforma o comprometimento de um host em um problema de cobrança e perda de dados: o arquivo compose passava as chaves do provedor para o contêiner, e os processos de backend herdavam o ambiente completo por meio de { ...process.env }, então um único printenv os despejava. Essas chaves então permitiram que ruflo__swarm_init e ruflo__agent_spawn iniciassem enxames controlados pelo atacante que consumiam a cota e a capacidade de computação da vítima.

O quinto passo é aquele que sobrevive à intrusão. Usando ruflo__agentdb_pattern-store, Noma inseriu uma política de conformidade SOC2 fabricada que instruía a IA a incorporar uma URL controlada pelo atacante em cada script de implantação que gerasse subsequentemente. Como o AgentDB existe precisamente para persistir esse tipo de padrão, de modo que o comportamento do agente melhore entre sessões, a entrada injetada comportou-se como o sistema foi projetado para se comportar. "Conversas futuras produzem resultados influenciados pelo atacante, e o usuário não tem como perceber", afirma o relatório de Noma. A Dark Reading, que noticiou a falha em 29 de julho, apresentou a distinção a um especialista externo: John Gallagher, vice-presidente da Viakoo, classificou-a como um tipo diferente de problema: "Isto não é explorar falhas de software, é envenenamento de memória."

As etapas restantes são pós-exploração convencional, executada com uma conveniência incomum./tmp, despejaram as conversas e as enviaram para fora. A persistência veio de gravar /app/beacon.js, adicionando uma require('./beacon.js') linha ao index.js e de matar o PID 1, após o que a política de reinício do Docker trouxe o contêiner de volta com o beacon ativo. A etapa final foi limpar o histórico do shell. Tudo isso decorreu de uma única solicitação não autenticada; nada na implantação padrão deteve a cadeia em nenhum momento.

A correção, e a parte que um patch não consegue alcançar

O mantenedor lançou o Ruflo 3.16.3 em até 24 horas após a divulgação de 30 de junho, e o GitHub publicou o aviso de segurança GHSA-c4hm-4h84-2cf3 em 1 de julho de 2026. A correção, registrada no repositório como ADR-166 e mesclada na solicitação de pull 2521, altera as configurações padrão em vez de apenas adicionar uma verificação:

• A ponte MCP liga-se a 127.0.0.1 por padrão; uma ligação pública exige MCP_AUTH_TOKEN, e o processo encerra com uma mensagem fatal na inicialização se o token estiver ausente.

• O middleware de token Bearer com comparação em tempo constante fica à frente da ponte.

• terminal_execute é controlado no servidor por trás de MCP_ENABLE_TERMINAL=true, desativado por padrão, e o controle é aplicado de forma idêntica em /mcp, /mcp/:group e no fluxo de autopilot — o elo ausente que permitia que a cadeia divulgada chegasse a um shell.

• O MongoDB exige autenticação, sendo necessária uma senha de root para que o contêiner seja iniciado.

• O contêiner de bridge executa um sistema de arquivos raiz somente leitura com tmpfs, uma lista de permissões CORS substitui o curinga, e travas de regressão de CI cobrem a configuração estática e o comportamento em tempo de execução.

Nada disso remove uma entrada já gravada no AgentDB. O aviso orienta operadores de qualquer instância exposta a bloquear imediatamente as portas 3001 e 27017 com firewall, rotacionar as chaves do provedor, auditar o armazenamento de padrões em busca de entradas injetadas agentdb_pattern-store e removê-las, auditar o MongoDB em busca de adulteração e reconstruir os contêineres a partir de imagens limpas. Sua advertência é incomumente direta: "Uma reimplantação com patch, sozinha, NÃO desfaz o envenenamento." A análise de Noma chega à mesma conclusão — auditar o armazenamento de padrões faz parte da remediação, e o patch não.

A razão é estrutural, e não fruto de descuido. Um armazenamento de padrões que molda a saída futura do modelo não tem como distinguir uma instrução aprendida legítima de uma plantada por um atacante; ambas chegam como padrões, e o sistema foi construído para confiar neles. Isso transforma uma vulnerabilidade de rede num problema de integridade de dados com um passivo desconhecido, e significa que a questão, para um operador, não é apenas se a porta estava acessível, mas o que a memória contém agora.

A hand-built HTML timeline card headed 'From disclosure to coverage', kicker 'RufRoot - disclosure timeline', subtitle 'Five dates, from the private report to the day the record was filed'. Six dated rows. 30 June 2026: Noma Labs discloses the flaw to Ruflo's maintainer with a working proof of concept. 1 July 2026: Ruflo 3.16.3 ships and GHSA-c4hm-4h84-2cf3 is published with CVSS 10.0. 9 July 2026: the CVE record for CVE-2026-59726 is published in the National Vulnerability Database, later marked Deferred. 29 July 2026: The Hacker News and Dark Reading report the flaw; Noma Labs publishes its research. 30 July 2026: SecurityWeek reports it, and the record is dated to this day. A separate amber note reads: no source we read reports exploitation in the wild at any point on this timeline. A footer cites The Hacker News, the GitHub advisory API, the NVD record and SecurityWeek.

O que está estabelecido e o que não está

O registro técnico aqui é primário e consistente. O aviso nomeia o pacote afetado (npm ruflo abaixo de 3.16.3), a versão corrigida, os endpoints exatos, o usuário do contêiner e as duas portas; as notas de lançamento do mantenedor descrevem a mesma cadeia; a análise de Noma fornece o detalhe da prova de conceito; e veículos independentes — The Hacker News e Dark Reading em 29 de julho de 2026, SecurityWeek em 30 de julho — relatam o mesmo mecanismo sem acrescentar detalhes contraditórios. Uma nota de pesquisa da Cloud Security Alliance datada de 5 de agosto de 2026 reformula a sequência e a coloca ao lado de falhas anteriores não autenticadas de MCP e de orquestração de agentes que ela havia acompanhado. O arquivo classifica o registro com confiança A, indiscutível, e o marca como um marco; sua classificação de severidade para o registro é alta, distinta da própria pontuação CVSS.

Um detalhe da pontuação merece ser declarado com precisão, porque dois documentos primários divergem. O GHSA-c4hm-4h84-2cf3 traz CVSS 10.0 no vetor AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — a mudança de escopo é o que o leva ao máximo. A cópia do mesmo advisory na página de lançamento da versão 3.16.3 descreve a pontuação como "CVSS 9.8 critical". O registro do National Vulnerability Database, verificado em 30 de outubro de 2026, publicado em 9 de julho de 2026 e marcado como Deferred, traz o 10.0 do GitHub como métrica secundária e nenhuma pontuação própria do NVD. Não encontramos explicação para a linha do 9.8, e este texto não a resolve.

Os números de adoção são mais modestos. A Noma Labs descreveu o projeto na época como tendo mais de 67.000 estrelas no GitHub, aproximadamente 10 milhões de downloads e cerca de 1 milhão de usuários ativos; o The Hacker News, conforme resumido pela Cloud Security Alliance, citou mais de 66.500 estrelas. As contagens de downloads e de usuários são da própria Noma e não foram verificadas de forma independente. A contagem de estrelas do repositório em 30 de outubro de 2026 era de 80.198 — uma verificação do alcance do projeto, não uma medida de exposição, e nenhuma fonte publicou quantas implantações eram realmente alcançáveis a partir de uma rede.

A hand-built HTML card headed 'Established, and not', kicker 'RufRoot - evidence', subtitle 'What the advisory, the release notes and the research support, against what nobody has shown'. Two columns. The left column, headed 'Established', lists: CVE-2026-59726 affects npm ruflo below 3.16.3 and is patched in 3.16.3; the default compose file bound the MCP bridge to 0.0.0.0 on port 3001 and MongoDB to 27017 without authentication; POST /mcp and POST /mcp/:group reached 233 tools and terminal_execute with no credential, running as node, uid 1000; Noma Labs confirmed an eight-step chain live on AWS EC2 with out-of-band callbacks, including an AgentDB pattern injection; the advisory was published 1 July 2026 with CVSS 10.0 and the fix shipped within 24 hours of the 30 June disclosure; the archive record is confidence A, undisputed, no real harm recorded, GLOBAL, MCP and INFRA. The right column, headed 'Not established', lists: that anyone exploited the flaw in the wild; how many Ruflo deployments were actually network-reachable; that any instance's AgentDB was poisoned, since no audit results are published; whether 9.8 in the release notes or 10.0 in the advisory is the intended score; Noma's counts of 10M downloads and 1M active users, which no independent source confirms; that any operator received notice beyond the public advisory. A footer cites GHSA-c4hm-4h84-2cf3, the Ruflo 3.16.3 release notes, Noma Labs and SecurityWeek.

O que não está estabelecido é justamente a parte mais facilmente inflada. Nem a Noma, nem o mantenedor, nem qualquer veículo que tenhamos lido afirma que a falha foi explorada em ambiente real, e o arquivo não registra nenhum dano concreto para esta entrada. A prova de conceito da Noma foi executada contra uma implantação controlada pelos pesquisadores na EC2, o que mostra o que uma instalação padrão permite, não o que qualquer instância de produção específica sofreu. Nenhuma contagem de implantações do Ruflo expostas à internet foi publicada, e nenhum operador publicou os resultados de uma auditoria do AgentDB, de modo que tanto a população afetada quanto a quantidade de memória envenenada existente são desconhecidas. A recomendação da Cloud Security Alliance de tratar implantações expostas como comprometimentos totais é uma postura de risco justificada pela exploração sem interação; não é evidência de que tenha ocorrido uma violação.

Por que o arquivo o classifica como um marco

A marca histórica do arquivo baseia-se em algo mais específico do que uma pontuação máxima. Uma vulnerabilidade de execução remota de código com CVSS 10,0 num serviço auto-hospedado popular é um género familiar, e a correção aqui chegou em 24 horas. O que distingue o RufRoot é que o exploit terminou no próprio pipeline de aprendizagem da IA, onde o remédio convencional — atualizar, reimplantar, fechar a porta — deixa a instrução injetada no lugar e ainda a moldar respostas. A nota da Cloud Security Alliance interpreta-o como um estudo de caso de um padrão que já tinha documentado em ferramentas de agente, incluindo uma cadeia de checkpoints do LangGraph e uma superfície não autenticada do AutoGen Studio, e argumenta que a memória persistente usada para moldar o comportamento do agente deve ser tratada como um armazenamento de dados sensíveis sob monitorização de integridade, e não como um cache.

Essa reformulação é a lição prática. O artefato visível deste incidente é uma dependência corrigida e um aviso publicado; o invisível é qualquer padrão que o AgentDB de um operador ainda possa conter, e não há ferramenta ou assinatura publicada que distinga uma política aprendida legítima de uma implantada. Para as organizações que executaram o arquivo compose padrão atrás de uma rede acessível, a resposta útil é a que tanto a Noma quanto o aviso dão: assuma que as chaves foram lidas, rotacione-as e inspecione a memória antes de confiar nas respostas que ela produz.