
Preuve de concept et laboratoire pour une évasion de sandbox n8n 2.42.0 : des nœuds Function/FunctionItem cachés exécutent du JS dans le processus principal, donnant aux membres authentifiés une RCE sur l'hôte.
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · n8n-function-vm2
n8n 2.42.0 - n8n GmbH
GHSA-j4p8-h8mh-rh8q a déplacé n8n-nodes-base.code vers le processus enfant task-runner JS. Le spawn en production ajoute --disallow-code-generation-from-strings et --disable-proto=delete. Ce qui reste, ce sont les nœuds qu'ils ont cachés au lieu de les déplacer. Function.node.ts est hidden: true. FunctionItem aussi. LangChain Code aussi. Le masquage dans la palette est un simple indicateur d'interface. La sauvegarde/import du JSON de workflow résout toujours le type. Le NODES_EXCLUDE par défaut ne contient que Execute Command et Local File Trigger. Le chemin d'exécution est un vm2 NodeVM 3.12.2 in-process dans le processus principal de n8n.
Un membre par défaut capable de créer un workflow peut exécuter du JS dans le processus principal de n8n. Caché ne signifie pas ACL.
| ID | pas encore de CVE |
| CWE | CWE-94, CWE-269 |
| CVSS | Élevé : 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Produit | n8n |
| Affecté | jusqu'à 2.42.0 (86c23326) ; résidu de GHSA-j4p8 |
| Auth | membre authentifié avec droits de création/import/exécution de workflow |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement |
En tant que membre par défaut, importer ou créer un workflow dont le type de nœud est n8n-nodes-base.function (ou functionItem, ou @n8n/n8n-nodes-langchain.code) et l'exécuter. Le JS s'exécute dans le processus principal de n8n.
C'est un RCE sur l'hôte avec l'UID de n8n : secrets de l'instance, ciphertext des identifiants des autres utilisateurs sur disque, la base de données. Prise de contrôle de l'instance par un membre multi-tenant. Pas une LPE OS. Pas non authentifié. Code v2 sur la même instance ne voit pas process de cette manière.
Même produit, résidu similaire : Databricks path join.
J'ai d'abord lu la vague de GHSA du 16 septembre 2026, puis mené dix chasses sur le tag [email protected]. Sandbox d'expressions, Code/Function/vm2, identifiants, webhooks, HTTP/SSRF, nœud Git, paquets communautaires, auth/SSO, injection de nœuds, API publique. La plupart des vulnérabilités Élevées de cette vague sont corrigées sur ce pin. Code n'était pas terminé.
Les règles de rupture v3 marquent déjà Function / FunctionItem comme supprimés. Sur 2.42.0, ce sont des résidus, pas un sandbox à long terme voulu. Function injecte aussi this.helpers, y compris des helpers que le runner JS liste comme non pris en charge. Je n'ai pas eu besoin d'un gadget vm2 public pour prouver la frontière de processus.
J'ai déployé un n8nio/n8n:2.42.0 standard, créé un compte membre (pas propriétaire d'instance), importé n8n-nodes-base.function, exécuté. Le pid=7 de Function est le PID principal de n8n. Le même JS dans Code v2 : hasProcess: false. Le processus enfant task-runner est le pid 26. Témoin N8N-FUNCTION-VM2-WITNESS.
Fausses pistes déjà consignées : type Function rejeté comme caché/inconnu (alors le nœud est en fait exclu) ; pid de Function égal à celui du processus enfant task-runner (alors il a déjà été déplacé) ; Code v2 voyant process (alors le runner n'est pas le contrôle) ; un gadget d'exploit vm2, un reverse shell, une LPE OS. Du théâtre. Le témoin, c'est le PID principal vs hasProcess: false.
cd lab
./run.sh
Cible uniquement http://127.0.0.1:18201. NODES_EXCLUDE par défaut. L'attaquant est un membre.
authenticated-as=member
function-fields pid=7 witness=N8N-FUNCTION-VM2-WITNESS
code-fields hasProcess=False pid=None
compare function_pid=7 code_pid=None main_pid=7 runner_pid=26 who=member
SUCCESS N8N-FUNCTION-VM2 who=member function_pid=7 code_pid=None main_pid=7 runner_pid=26 N8N-FUNCTION-VM2-WITNESS
Ajouter n8n-nodes-base.function, n8n-nodes-base.functionItem et @n8n/n8n-nodes-langchain.code au NODES_EXCLUDE par défaut, ou les router via JsTaskRunnerSandbox comme le fait déjà Code v2. Le hidden de la palette ne suffit pas.
Function.node.ts · Code.node.ts · nodes.config.ts · task-runner-process-js.tsGNU Affero GPL v3.0. Voir LICENSE. Lab en loopback uniquement. Aucune garantie.