Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-33937 — Vulnérabilité d'exécution de code à distance par injection AST dans Handlebars.js | Kitploit
Outils/GitHubGitHub/eqstlab/cve-2026-33937
Analyse des VulnérabilitésExploitationExploitation d'Applications WebSécurité WebArticles et RechercheApprentissage et ÉducationDéveloppement de Charges UtilesLabs et Pratique
GitHubeqstlab/cve-2026-33937

CVE-2026-33937

Vulnérabilité d'exécution de code à distance par injection AST dans Handlebars.js

Voir le dépôt
21il y a 3 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Cet article est une publication de recherche de l'EQSTLab.

PoC référencé : dinhvaren/cve-2026-33937

CVE-2026-33937

★ CVE-2026-33937 — PoC d'injection AST et d'exécution de code à distance dans Handlebars.js ★

https://github.com/user-attachments/assets/99e383e7-e71f-4e10-8c62-f50abff8b4f5


Description

CVE-2026-33937 : vulnérabilité d'exécution de code à distance par injection AST dans Handlebars.js

Versions affectées4.0.0 – 4.7.8
Version corrigée4.7.9
Score CVSS9.8 (Critique)

Une vulnérabilité de confusion de type dans Handlebars.js provient du fait que Handlebars.compile() accepte non seulement une chaîne de modèle, mais aussi un objet AST pré-analysé (JSON) en entrée. Un attaquant qui contrôle la valeur passée à compile() peut fournir un objet AST malveillant dans lequel le champ value d'un nœud NumberLiteral est remplacé par une chaîne JavaScript arbitraire. Étant donné que le générateur de code interne insère ce champ directement dans le corps de la fonction JavaScript émise sans assainissement, la fonction résultante exécute le code contrôlé par l'attaquant lors du rendu — permettant une exécution de code à distance sur le serveur.


Configuration du laboratoire

Créez et exécutez l'environnement vulnérable avec Docker :

Construire l'image

root@kitploit:~
docker build -t cve-2026-33937-server .

Exécuter le conteneur

root@kitploit:~
docker run --name cve-2026-33937 -p 12701:12701 -p 9229:9229 cve-2026-33937-server

Ou utilisez les scripts npm fournis :

root@kitploit:~
npm run docker:up   # build + run in one step

L'application est servie à l'adresse http://localhost:12701.


Comment utiliser

Interface web

Ouvrez http://localhost:12701 dans un navigateur. La page présente une interface de création d'e-mails B2B. Les valeurs de champs fournies par l'utilisateur sont interpolées dans une chaîne de modèle Handlebars côté client, puis envoyées au serveur pour le rendu. Injectez une charge utile Handlebars malveillante via les champs de saisie ou directement via l'API.

API directe

root@kitploit:~
# POST crafted template to the vulnerable endpoint
curl -s -X POST http://localhost:12701/api/email/preview \
  -H "Content-Type: application/json" \
  -d '{"subject":"test","editorTemplateData":"<PAYLOAD>"}'

Remplacez <PAYLOAD> par une charge utile d'injection AST ciblant Handlebars.compile().


Analyse

Point de terminaison vulnérable

root@kitploit:~
POST /api/email/preview

Le serveur accepte un corps JSON contenant editorTemplateData et le transmet directement à Handlebars.compile() sans assainissement ni application de liste autorisée :

root@kitploit:~
// app.js
const renderEmail = Handlebars.compile(editorTemplateData);

Cause racine technique

Handlebars.compile() est documenté comme acceptant une chaîne de modèle, mais sa vérification de type interne permet également de passer directement un objet AST pré-analysé. Dans javascript-compiler.js, le visiteur NumberLiteral() émet le champ value du nœud tel quel dans la source JavaScript générée, sans validation de type ni assainissement :

root@kitploit:~
// javascript-compiler.js (simplified)
NumberLiteral(number) {
  this.pushStackLiteral(number.value);   // value inserted as-is into emitted JS
}

Si un attaquant fournit un objet AST malveillant dans lequel number.value est une chaîne contenant du JavaScript arbitraire (par exemple, "1; require('child_process').execSync(...)") au lieu d'un littéral numérique, le corps de la fonction émise contient et exécute ce code lors du rendu.

Le schéma dangereux dans l'application vulnérable est :

root@kitploit:~
const render = Handlebars.compile(userInput);  // userInput may be a crafted AST object
render(safeContextData);                        // attacker code runs here

Note sur la technique d'exploitation : Les PoC publics existants (y compris celui référencé) réalisent l'injection via un nœud NumberLiteral combiné à un helper lookup. Ce PoC confirme la même primitive RCE en utilisant un nœud BooleanLiteral combiné au helper intégré log, démontrant que la confusion de type n'est pas limitée à un seul type de nœud ou à une seule fonction helper.

Déroulement de l'attaque

  1. L'attaquant envoie une requête POST à /api/email/preview avec une valeur editorTemplateData malveillante.
  2. Le serveur appelle Handlebars.compile() sur l'objet AST contrôlé par l'attaquant.
  3. Le compilateur ignore l'analyse syntaxique et traite directement l'objet AST fourni par l'attaquant, en transmettant le nœud littéral injecté au générateur de code.
  4. La génération de code produit une fonction JavaScript qui s'échappe du bac à sable du modèle.
  5. L'appel de render() déclenche l'exécution de JavaScript arbitraire dans le processus serveur.

Pourquoi c'est important

Lorsque Handlebars est utilisé dans un environnement backend Node.js, cette vulnérabilité mène à une exécution de code côté serveur, contrairement à une XSS classique côté client. L'attaque n'exige pas qu'une sortie soit renvoyée à l'utilisateur ; la charge utile s'exécute dans le processus Node.js avec les mêmes privilèges que l'application. Selon le déploiement :

  • Les fichiers sensibles (par exemple, les secrets de l'application, /etc/passwd) peuvent être lus et exfiltrés.
  • Des connexions sortantes peuvent être établies pour un reverse shell.
  • Des mécanismes de persistance peuvent être installés si le processus dispose d'un accès suffisant au système de fichiers.

Scénario

root@kitploit:~
+-------------------------------------------+
|                  Attacker                 |
+-------------------------------------------+
                      |
                      | POST /api/email/preview
                      | {"editorTemplateData": "<malicious payload>"}
                      v
+-------------------------------------------+
|   Handlebars.compile(editorTemplateData)  |
|   (No sanitization — app.js:17)           |
+-------------------------------------------+
                      |
                      | AST node injection
                      | breaks template sandbox
                      v
+-------------------------------------------+
|  Arbitrary JS Execution (Server Process)  |
+-------------------------------------------+
                      |
                      | Read sensitive files, spawn shell,
                      | exfiltrate secrets, etc.
                      v
+-------------------------------------------+
|        Remote Code Execution (RCE)        |
+-------------------------------------------+

Atténuation

  1. Mettez à niveau Handlebars.js vers 4.7.9 ou une version ultérieure.
    La version 4.7.9 introduit une validation stricte du type d'entrée dans compile(), rejetant les arguments qui ne sont pas des chaînes avant le début de la génération de code.

  2. Appliquez une vérification de type avant d'appeler compile().
    Si une mise à niveau immédiate n'est pas possible, validez que l'argument est toujours une string au niveau du site d'appel :

    root@kitploit:~
    if (typeof templateInput !== 'string') throw new TypeError('Template must be a string');
    const render = Handlebars.compile(templateInput);
    
  3. Utilisez handlebars/runtime pour la précompilation au moment du build.
    Précompilez les modèles au moment du build avec la CLI Handlebars et distribuez uniquement le bundle runtime. La version runtime n'inclut pas compile(), ce qui élimine entièrement la surface d'attaque pour les déploiements en production.


Avertissement

Ce dépôt est destiné uniquement à la recherche en sécurité, à l'éducation et à la démonstration contrôlée de vulnérabilités. Il ne doit pas être utilisé pour tester ou exploiter des systèmes sans l'autorisation écrite explicite du propriétaire du système. L'objectif de ce projet est d'aider les chercheurs en sécurité, les défenseurs et les développeurs à comprendre la vulnérabilité, à valider l'exposition dans des environnements de laboratoire contrôlés et à appliquer des mesures d'atténuation efficaces.


Références

  • https://handlebarsjs.com/
  • https://github.com/handlebars-lang/handlebars.js
Télécharger l’outil