n8n : la faille CVE-2026-86083 dans le moteur d'expression legacy — comprendre et migrer vers vm
Par Clément Lacaille (Tech-Bharat) · Publié le 11 septembre 2026 · 5 min de lecture · notre méthode
Bundle FlowKit Complet — 269 €
12 workflows n8n prêts à importer, guide en français, garantie 14 jours
Une instance n8n self-hosted qui tourne en arrière-plan depuis des mois, sans qu'on y touche parce que « ça marche », est un classique de l'automatisation no-code. C'est précisément ce scénario que vise CVE-2026-86083 : une faille de sécurité de sévérité élevée (CVSS 7.7) découverte dans le moteur d'expression « legacy » de n8n, celui qui interprète chaque {{ $json.champ }} glissé dans un node. Si vos workflows — qu'ils viennent d'un pack FlowKit ou que vous les ayez construits vous-même — s'appuient sur des expressions n8n (c'est le cas de la quasi-totalité des installations), ce correctif mérite un traitement prioritaire plutôt qu'une mise à jour de routine.
Qu'est-ce que le moteur d'expression n8n, et pourquoi il en existe deux versions
Chaque fois qu'un node n8n contient une valeur entre doubles accolades — {{ $json.email }}, {{ $now.toISO() }} — cette chaîne est envoyée à un moteur d'expression qui l'interprète et renvoie une valeur. C'est le mécanisme décrit dans notre guide de la syntaxe des expressions n8n, et il tourne en continu, y compris dans des workflows qui ne contiennent aucun node Code.
n8n a longtemps proposé deux implémentations de ce moteur : le moteur legacy, plus ancien, qui construit dynamiquement du texte source JavaScript puis l'exécute ; et le moteur vm, plus récent, qui évalue l'expression dans un contexte V8 isolé via isolated-vm, avec un cloisonnement beaucoup plus strict entre le code évalué et le reste du processus n8n. Sur les versions patchées, vm est désormais le moteur par défaut, et le legacy est officiellement déprécié.
La faille CVE-2026-86083 : une expression qui réécrit ce qu'elle exécute
Le détail technique, documenté dans l'avis de sécurité publié sur la GitLab Advisory Database, est instructif : le moteur legacy générait son texte source en appelant JSON.stringify, une fonction globale mutable, pour imprimer des littéraux de chaîne synthétiques et interpoler des données de fuseau horaire. Une expression malveillante pouvait remplacer cette référence globale à JSON.stringify — et faire en sorte que le texte source généré ensuite contienne du code exécutable contrôlé par l'attaquant. Autrement dit : le moteur censé isoler l'expression de son environnement pouvait être retourné contre lui-même pour s'évader du bac à sable.
La faille est classée CWE-94 (« Improper Control of Generation of Code ») avec un score CVSS 4.0 de 7.7, correspondant à un vecteur réseau, un privilège requis faible et aucune interaction utilisateur nécessaire — dès lors qu'une donnée non fiable (un champ de webhook, un contenu d'e-mail traité automatiquement, une entrée de formulaire) se retrouve dans une expression évaluée par une instance non corrigée. Le correctif est disponible dans les versions 1.123.76, 2.37.7 et 2.38.2 : il fait passer les deux étapes de génération de code par une référence capturée au chargement du module, de sorte qu'une modification ultérieure de l'état global ne puisse plus altérer le code source produit. Seules les instances tournant encore sur le moteur legacy sont affectées — le moteur vm, non concerné par ce mécanisme, était déjà à l'abri avant même le correctif.
Pourquoi ce type de faille n'est pas un accident isolé
Ce n'est pas la première fois qu'un bac à sable JavaScript construit « au niveau du langage » — sans isolation de processus — se fait contourner par un détournement astucieux des primitives partagées. Une étude d'Abdullah AlHamdan et Cristian-Alexandru Staicu, présentée au USENIX Security Symposium 2023 (« SandDriller: A Fully-Automated Approach for Testing Language-Based JavaScript Sandboxes »), a testé automatiquement six systèmes de sandboxing JavaScript répandus et y a découvert huit vulnérabilités d'évasion jusqu'alors inconnues. La conclusion des auteurs rejoint exactement ce qu'illustre CVE-2026-86083 : un bac à sable qui repose sur des astuces de langage (proxies, gel de prototypes, capture de références) plutôt que sur une isolation de processus reste structurellement fragile, quelle que soit la rigueur de son implémentation. C'est cette même logique qui a motivé le passage de n8n au moteur vm, ainsi que l'isolation du node Code dans des Task Runners séparés depuis n8n 2.0 — deux chantiers de durcissement distincts, mais portés par le même principe.
Votre instance est-elle concernée ?
Si vous utilisez n8n Cloud, rien à faire : l'éditeur applique les correctifs côté serveur. Si vous êtes en self-hosted — Docker, VPS, Kubernetes — vérifiez votre version dans Réglages > À propos, puis contrôlez si la variable d'environnement N8N_EXPRESSION_ENGINE force explicitement le moteur legacy dans votre configuration ; c'est le seul cas où une instance à jour resterait tout de même vulnérable. Avant toute mise à jour, suivez la méthode habituelle plutôt qu'un docker compose pull à l'aveugle : sauvegardez votre base (guide de sauvegarde PostgreSQL pour n8n self-hosted), épinglez un tag précis, et référez-vous à notre procédure de mise à jour n8n sous Docker sans rien casser pour un rollback propre en cas de souci.
Migrer vers le moteur vm
La migration tient en trois points :
- Mettez à jour n8n vers 1.123.76, 2.37.7, 2.38.2 ou une version ultérieure. Sur ces versions, le moteur vm est activé par défaut, sans configuration supplémentaire.
- Retirez toute valeur
legacyde la variableN8N_EXPRESSION_ENGINEdans votre docker-compose, votre fichier.envou vos secrets Kubernetes. Ne la fixez jamais àlegacy, y compris temporairement pour « tester » un ancien comportement. - Testez vos workflows critiques après redémarrage, en particulier ceux qui manipulent des dates, des fuseaux horaires ou des chaînes construites dynamiquement — ce sont les usages les plus susceptibles de révéler une divergence de comportement entre les deux moteurs.
Bonne hygiène des expressions, au-delà du correctif
La mise à jour ferme cette faille précise, mais deux réflexes restent valables quel que soit le moteur utilisé. D'abord, ne laissez jamais une donnée totalement non fiable (payload de webhook public, pièce jointe d'e-mail, champ de formulaire ouvert) alimenter directement une expression complexe ou un node Code sans validation intermédiaire — c'est le même principe que pour la sécurisation d'un webhook n8n exposé publiquement. Ensuite, gardez vos credentials hors des expressions elles-mêmes : ils doivent rester dans le gestionnaire de credentials chiffré de n8n, jamais concaténés dans une chaîne évaluée dynamiquement.
Check-list
- Version n8n vérifiée : 1.123.76 / 2.37.7 / 2.38.2 ou supérieure.
- Variable
N8N_EXPRESSION_ENGINEabsente ou explicitement àvm, jamais àlegacy. - Sauvegarde PostgreSQL prise avant la mise à jour, tag Docker épinglé.
- Workflows sensibles aux dates et aux chaînes dynamiques retestés après migration.
- Données non fiables jamais injectées telles quelles dans une expression ou un node Code.
Les workflows des packs FlowKit reposent, comme n'importe quel workflow n8n, sur des expressions standard : ils tournent sans modification sur une instance à jour utilisant le moteur vm. Si la traçabilité fait partie de vos exigences — savoir qui a modifié quoi, et quand, sur une instance qui vient d'être corrigée — le Pack Conformité & Audit (149 €) inclut une piste d'audit prête à l'emploi, complémentaire de cette mise à jour de sécurité plutôt qu'un substitut à celle-ci.
FAQ
Questions fréquentes
Les instances n8n Cloud sont-elles concernées par CVE-2026-86083 ?
Non, pas de votre côté : n8n Cloud est géré par l'éditeur, qui applique les correctifs de sécurité sur son infrastructure sans action de votre part. Cette faille concerne les instances self-hosted (Docker, VPS, Kubernetes) que vous administrez vous-même et dont la version n'a pas encore été mise à jour vers un correctif.
Comment savoir quel moteur d'expression utilise mon instance n8n ?
Vérifiez d'abord votre numéro de version dans Réglages > À propos : si vous êtes en dessous de 1.123.76, 2.37.7 ou 2.38.2, vous êtes potentiellement sur le moteur legacy vulnérable. Ensuite, contrôlez la variable d'environnement N8N_EXPRESSION_ENGINE de votre déploiement : si elle vaut explicitement « legacy », changez-la ou supprimez-la — sur une version patchée, l'absence de cette variable fait basculer automatiquement sur vm, le moteur par défaut.
Migrer vers le moteur vm va-t-il casser mes expressions existantes ?
Dans l'immense majorité des cas, non : le moteur vm respecte la même syntaxe d'expression n8n et les mêmes variables (`$json`, `$node`, `$now`…). Les rares cas de divergence concernent des usages avancés qui s'appuyaient sur un comportement non documenté du moteur legacy. Testez vos workflows critiques après la mise à jour, en particulier ceux qui manipulent des dates ou des chaînes générées dynamiquement, avant de considérer la migration terminée.
Que faire si je ne peux pas mettre à jour mon instance immédiatement ?
En attendant la mise à jour, limitez au maximum ce qui peut influencer le contenu d'une expression évaluée par l'instance : données de webhooks non authentifiés, champs de formulaire publics, contenus d'e-mails traités automatiquement. Ce n'est qu'une atténuation temporaire — la seule correction réelle est la mise à jour vers une version patchée, à planifier en priorité plutôt qu'en tâche de fond.