Envio de registos, alertas e telemetria através de um diodo de dados

Descubra como
Utilizamos inteligência artificial para as traduções dos sítios e, embora nos esforcemos por garantir a exatidão, estas podem nem sempre ser 100% precisas. Agradecemos a sua compreensão.

CVE-2026-25049: Sandbox de expressões que leva à execução remota de código no n8n

Por Loc Nguyen, líder da equipa de testes de penetração
Partilhar esta publicação

Em fevereiro de 2026, foi divulgada publicamente uma vulnerabilidade crítica de fuga da sandbox no n8n, a plataforma de código aberto de automação de fluxos de trabalho amplamente utilizada. Identificada como CVE-2026-25049, esta falha permite que utilizadores autenticados contornem a sandbox de avaliação de expressões e executem comandos de sistema arbitrários no servidor anfitrião, conseguindo a execução remota total de código com uma pontuação CVSS v3.1 de 9,9.

No âmbito do Programa de Bolsas de EstudoOPSWAT , os nossos bolseiros realizaram uma análise técnica exaustiva da vulnerabilidade CVE-2026-25049, examinando a sua causa principal, o mecanismo de exploração e o impacto nas organizações.

Este blog apresenta uma análise detalhada da vulnerabilidade — desde a arquitetura de processamento de expressões do n8n e os seus controlos de segurança em camadas até à técnica específica que contorna simultaneamente todas as cinco camadas de defesa.

A CVE-2026-25049 é uma vulnerabilidade crítica de fuga da sandbox de expressões no n8n, classificada sob o CWE-913: Controlo inadequado de recursos de código geridos dinamicamente. A falha afeta todas as versões do n8n anteriores à 1.123.17, bem como as versões 2.0.0 a 2.5.1, e foi corrigida nas versões 1.123.17 e 2.5.2. Permite que utilizadores autenticados com permissões de criação de fluxos de trabalho criem expressões JavaScript maliciosas que contornam a sandbox de expressões da plataforma, conseguindo, em última instância, a execução arbitrária de comandos no servidor anfitrião.

Figura 1: CVE-2026-25049 (fonte: NVD)

A vulnerabilidade é particularmente grave porque o n8n ocupa frequentemente uma posição privilegiada na infraestrutura de uma organização. Enquanto centro de automatização de fluxos de trabalho, o n8n mantém normalmente acesso direto a APIs internas, bases de dados, repositórios de credenciais e serviços de terceiros. Uma instância do n8n comprometida não se limita a expor o servidor de automatização — constitui um ponto de acesso a todos os sistemas ligados, ampliando drasticamente o alcance da exploração.

A CVE-2026-25049 não é uma descoberta isolada, mas sim uma forma de contornar a correção da CVE-2025-68613, uma falha anterior de fuga da sandbox no avaliador de expressões do n8n. Apesar da implementação de defesas em várias camadas após a vulnerabilidade inicial, uma lacuna fundamental na forma como o sanitizador processa os tipos de nós da Árvore de Sintaxe Abstrata (AST) do JavaScript permitiu que a classe original de ataque ressurgisse através de um vetor sintático diferente. Este padrão — em que uma correção aborda a técnica de exploração específica em vez da fraqueza de design subjacente — destaca o desafio persistente de proteger ambientes de avaliação de código dinâmico.

A vulnerabilidade foi divulgada a 4 de fevereiro de 2026, juntamente com outros dez alertas de segurança relativos ao n8n, e foi analisada de forma independente por várias equipas de investigação em segurança.

Sobre o n8n

A n8n é uma plataforma de código aberto para automação de fluxos de trabalho que permite às organizações ligar sistemas, automatizar processos e criar integrações entre centenas de serviços. Com uma ampla adoção e mais de 1 300 integrações disponíveis, a n8n tornou-se uma das ferramentas mais populares na sua categoria, utilizada por equipas de desenvolvimento e empresas para automatizar tudo, desde ferramentas internas até fluxos de dados essenciais para o negócio.

Figura 2: Um exemplo de um fluxo de trabalho do n8n.

A plataforma suporta implementações tanto auto-hospedadas como na nuvem e oferece um criador visual de fluxos de trabalho, além de suporte direto a JavaScript para lógica personalizada. A arquitetura do n8n é baseada em nós: os fluxos de trabalho são compostos por nós interligados que transmitem dados em formato JSON entre gatilhos, ações e etapas de função. A execução pode ser feita no modo manual para testes ou no modo de produção para implementação em tempo real. Esta arquitetura, combinada com suporte nativo para expressões JavaScript e acesso a APIs internas e armazenamentos de credenciais, torna o n8n uma poderosa ferramenta de automação — mas também um alvo de alto valor quando surgem vulnerabilidades.

Contexto técnico

Árvores de sintaxe abstrata

Uma Árvore de Sintaxe Abstrata (AST) é uma representação hierárquica do código-fonte produzida por um analisador sintático. Em vez de tratar o código como uma cadeia de caracteres plana, uma AST decompõe-no em nós estruturados que representam os seus elementos sintáticos — declarações de variáveis, expressões de funções, expressões de membros, identificadores e literais.

Figura 3: Fases do compilador.

Compreender os tipos de nós AST é essencial para esta análise, uma vez que os controlos de segurança do n8n operam ao nível da AST. Os sanitizadores inspecionam tipos de nós específicos para detetar e bloquear padrões perigosos. A vulnerabilidade aproveita-se do facto de que a mesma operação semântica — aceder à propriedade de um objeto — pode produzir tipos de nós AST totalmente diferentes, dependendo da sintaxe JavaScript utilizada.

Figura 4: Alguns nós AST em JavaScript.

Por exemplo, a expressão `obj.constructor ` gera um nó `MemberExpression `, enquanto `const { constructor } = obj` gera uma `VariableDeclaration` que contém um `ObjectPattern` com um nó `Property`. Ambas extraem a mesma propriedade, mas as estruturas da AST são fundamentalmente diferentes — e os sanitizadores do n8n apenas inspecionam o primeiro padrão.

Avaliação de expressões e arquitetura de segurança do n8n

A arquitetura do n8n está organizada em cinco camadas: Frontend, CLI, Core, Workflow e Nodes. A camada Workflow é responsável pela avaliação de expressões, que é o componente relevante para esta vulnerabilidade.

Figura 5: Visão geral do fluxo do n8n.

O n8n permite aos utilizadores incorporar expressões JavaScript nos parâmetros dos nós do fluxo de trabalho para manipular dados de forma dinâmica. Estas expressões são avaliadas do lado do servidor utilizando uma biblioteca chamada Tournament, que analisa as expressões numa AST antes da execução. Os ganchos de sanitização são inseridos diretamente no processo de criação do Tournament, realizando verificações durante a construção da AST para interceptar padrões perigosos antes da execução de qualquer código.

Figura 6: Criação inicial do torneio.

Uma vez que estas expressões são executadas no mesmo processo Node.js que o servidor n8n, a plataforma implementa cinco camadas de segurança distintas, concebidas para impedir que código não confiável escape da sandbox.

Camada 1 - Substituição do contexto global

Antes de qualquer expressão ser avaliada, o n8n cria um contexto de execução restrito, substituindo objetos e funções globais perigosos. Propriedades como document, window, globalThis, eval, setTimeout, setInterval e Function são substituídas por objetos vazios, impedindo o acesso direto a essas funcionalidades.

Figura 7: Iniciar o Contexto Global.
Figura 8: Substituir todas as funções perigosas.

Esta abordagem tem uma limitação inerente: se um atacante conseguir escapar do contexto restrito e aceder ao objeto de processo global real, as propriedades sobrescritas tornam-se irrelevantes.

Camada 2 - Validação por expressões regulares

Antes de a expressão chegar ao avaliador, o n8n aplica uma verificação de expressão regular à cadeia de caracteres da expressão em bruto para bloquear o acesso à propriedade do construtor — um vetor comum para obter o construtor Function e conseguir a execução do código.

Figura 9: Validação por expressão regular.

A expressão regular /\.\s*constructor/gm deteta o acesso à propriedade .constructor através da notação de ponto. No entanto, esta verificação é fundamentalmente limitada, uma vez que o JavaScript oferece várias formas sintáticas de aceder à mesma propriedade, nem todas as quais envolvem a notação de ponto.

Camada 3 - Sanitizador de tempo de execução AST – PrototypeSanitizer

A defesa mais sofisticada é ativada durante a construção do AST. O gancho PrototypeSanitizer percorre o AST e inspeciona os nós MemberExpression para determinar se a propriedade acedida consta numa lista de bloqueio de propriedades de objetos inseguras — incluindo constructor, __proto__, prototype, mainModule e binding.

Figura 10: Protótipo de desinfetante.

O sanitizador lida com três casos: notação de ponto (obj.prop), em que verifica o nome do identificador; notação de colchetes estática (obj['prop']), em que verifica o valor da cadeia de caracteres literal; e expressões dinâmicas, que são envolvidas numa função de sanitização em tempo de execução. Conforme ilustrado na Figura 10, apenas os nós MemberExpression são inspecionados — os padrões de desestruturação não são percorridos.

Camada 4 - Função de sanitização do AST em tempo de execução ThisSanitizer

Adicionado como uma correção direta para a vulnerabilidade CVE-2025-68613, o FunctionThisSanitizer intercepta as Expressões de Função Invocadas Imediatamente (IIFEs) e reescreve-as para associar `this` a um objeto vazio. Isto impede a técnica utilizada na exploração original, em que (function(){ return this })() provocava a fuga do objeto global do processo através da referência `this` não associada.

Figura 11: Função GlobalThisSanitizer

É importante referir que este sanitizador só processa nós FunctionExpression. Ele sai explicitamente da execução antecipadamente para qualquer entidade chamada que não seja uma FunctionExpression, incluindo funções-seta.

Propriedades perigosas, como `eval`, `Function` e `process.mainModule`, são removidas ou substituídas no contexto de execução, impedindo o acesso direto a primitivas de execução de código, mesmo que as camadas anteriores sejam contornadas.

Análise de vulnerabilidade

Causa principal

A causa principal da vulnerabilidade CVE-2026-25049 reside numa suposição comum a todas as cinco camadas de segurança: cada camada partia do princípio de que o acesso às propriedades ocorreria através da notação de ponto (obj.constructor) ou da notação entre colchetes (obj['constructor']). Nenhuma delas teve em conta a sintaxe de desestruturação do JavaScript.

A desestruturação em JavaScript permite extrair propriedades de objetos utilizando uma estrutura AST fundamentalmente diferente:

// Traditional access - produces MemberExpression node
obj.constructor; // Blocked by regex, AST sanitizer, and runtime checks

// Destructuring - produces ObjectPattern → Property node
const { constructor } = obj; // Not checked by any layer

Embora ambos os padrões alcancem o mesmo resultado, produzem representações AST totalmente diferentes. O PrototypeSanitizer apenas inspeciona nós MemberExpression, e a expressão regular apenas corresponde a padrões .constructor. As atribuições de desestruturação criam nós VariableDeclaration → ObjectPattern → Property, que nenhum dos sanitizadores percorre.

A isto acresce a forma como o n8n lida com as funções-seta. O FunctionThisSanitizer intercepta apenas nós FunctionExpression e reescreve-os para vincular `this` a um contexto seguro. As funções-seta produzem nós AST do tipo ArrowFunctionExpression, que o sanitizador não processa. Uma vez que as funções-seta herdam `this` do seu âmbito circundante (o `this` léxico), permitem o acesso ao contexto global não sanitizado.

Em conjunto, estas duas falhas resultam numa evasão total: a desestruturação extrai o construtor Function sem ativar quaisquer verificações de acesso às propriedades, e as funções-seta proporcionam um contexto de execução que o FunctionThisSanitizer não intercepta.

Exploração

A exploração combina ambas as falhas para contornar todas as camadas de segurança simultaneamente. Os nossos colegas identificaram o seguinte percurso de exploração:

Passo 1 - Inserção da função-seta. A carga útil começa com uma função-seta envolvida numa Expressão de Função Invocada Imediatamente (IIFE):

={{(() => {
// Função-seta - ignora o FunctionThisSanitizer
...
})()}}

O FunctionThisSanitizer verifica se o destinatário da chamada é uma FunctionExpression; uma vez que se trata de uma ArrowFunctionExpression, o sanitizer retorna antecipadamente sem reescrever a chamada. A função-seta é executada com acesso total ao contexto global real.

Passo 2 - Desestruturação de bypass. Dentro da função-seta, a desestruturação extrai o construtor `Function` de uma instância da função-seta:

const { constructor } = () => {};

Como se trata de uma atribuição de desestruturação, a AST contém um nó ObjectPattern em vez de um MemberExpression. A verificação por expressão regular não deteta nenhum padrão .constructor, e o PrototypeSanitizer nunca inspeciona o nome da propriedade. O atacante detém agora uma referência ao construtor Function.

Passo 3 - Execução de código dinâmico. Com o construtor da função obtido, o atacante cria e executa código arbitrário:

return constructor(
'return process.mainModule.require("child_process").execSync("whoami").toString()',
)();

A função construída dinamicamente é executada fora do contexto da sandbox com acesso total ao objeto de processo do Node.js, permitindo a execução de comandos de sistema arbitrários no host.

Figura 12: Carga útil de ataque final

Prova de Conceito

Para demonstrar o impacto desta vulnerabilidade na prática, os nossos investigadores reproduziram a exploração num ambiente de laboratório controlado. O cenário de ataque envolve a hospedagem de uma instância vulnerável do n8n e a importação de um fluxo de trabalho que contém a carga maliciosa num parâmetro de nó — visando especificamente o nó «Edit Fields», que permite a avaliação de expressões.

Figura 13: O administrador importa um fluxo de trabalho malicioso.

Assim que o fluxo de trabalho é acionado, a carga maliciosa contorna todas as cinco camadas de sanitização e executa um shell reverso no servidor anfitrião, devolvendo ao atacante a capacidade total de execução de comandos.

Figura 14: Execução da carga útil através de um gatilho de fluxo de trabalho.

Escalada de webhook para RCE sem autenticação

A gravidade desta vulnerabilidade aumenta significativamente quando combinada com a funcionalidade de webhooks do n8n. O n8n permite que os fluxos de trabalho exponham pontos de extremidade HTTP como webhooks com opções de autenticação configuráveis, incluindo tokens de portador, autenticação básica e — o que é mais grave — sem qualquer tipo de autenticação. Um atacante com acesso à criação de fluxos de trabalho pode configurar um webhook público com a autenticação: «nenhuma», incorporar a carga útil RCE num nó conectado e ativar o fluxo de trabalho. Nesse momento, qualquer pedido HTTP para o URL do webhook — proveniente de qualquer lugar na Internet — desencadeia a execução de comandos arbitrários no servidor anfitrião.

Este caminho de escalada transforma a vulnerabilidade CVE-2026-25049 de uma vulnerabilidade interna e autenticada num vetor de ataque efetivamente não autenticado com exposição a toda a Internet.

Mitigação

A equipa do n8n corrigiu a vulnerabilidade CVE-2026-25049 nas versões 1.123.17 e 2.5.2, implementando uma verificação adequada dos tipos em tempo de execução nas funções de sanitização e alargando a cobertura da AST para lidar com padrões de desestruturação. As organizações que utilizam as versões afetadas devem atualizar imediatamente.

Se não for possível efetuar uma atualização imediata, os administradores devem restringir as permissões de criação e edição de fluxos de trabalho apenas a utilizadores de total confiança e implementar o n8n num ambiente reforçado, com privilégios restritos do sistema operativo e acesso à rede.

Dada a gravidade crítica e a facilidade de exploração — especialmente quando combinada com webhooks públicos —, as organizações devem também auditar os fluxos de trabalho existentes em busca de expressões suspeitas, monitorizar a execução de comandos de sistema anómalos originados do processo n8n e rever as configurações dos webhooks para detetar quaisquer pontos de extremidade expostos sem autenticação.

Mitigação com OPSWAT

Ao utilizar OPSWAT , as organizações podem identificar rapidamente os componentes n8n vulneráveis na sua infraestrutura e tomar medidas antes que ocorra qualquer exploração. OPSWAT , uma tecnologia fundamental da plataforma MetaDefender®, fornece um inventário abrangente de todos os componentes de software, bibliotecas e dependências em uso no ambiente de uma organização.

Figura 15: Detecção do CVE-2026-25049 no OPSWAT

Conforme ilustrado na Figura 15, MetaDefender analisou o ficheiro package.json que contém a dependência n8n e classificou automaticamente a vulnerabilidade CVE-2026-25049 como «Crítica», apresentando o intervalo de versões afetadas e as versões corrigidas recomendadas para a correção. Isto permite que as equipas de segurança identifiquem e priorizem rapidamente a vulnerabilidade em todo o seu ambiente de implementação.

OPSWAT está disponível no MetaDefender e no MetaDefender Software Chain™, permitindo que as equipas de segurança:

  • Localize rapidamente os componentes vulneráveis - Identifique imediatamente as dependências de código aberto afetadas por vulnerabilidades de fuga da sandbox e de execução de código, permitindo uma correção ou remoção rápida.
  • Garantir a aplicação proativa de correções e atualizações - Monitorizar continuamente os componentes de código aberto para detetar pacotes desatualizados ou inseguros, permitindo atualizações atempadas e reduzindo a exposição a riscos.
  • Manter a conformidade e a prestação de contas - Cumprir os requisitos regulamentares, à medida que os quadros normativos exigem cada vez mais transparência nas cadeias de abastecimento de software.

Referências

Mantenha-se atualizado com OPSWAT!

Inscreva-se hoje para receber as últimas actualizações da empresa, histórias, informações sobre eventos e muito mais.