new Function, old trick
PraisonAI’s codeMode ran model-written JavaScript behind a regex, and the constructor chain walked round it
Two records, 9.9 and 9.8, describe the same escape twice. Two more at 8.8 describe a command allowlist that read only the first word.
PraisonAI’s codeMode tool ran model-written JavaScript inside new Function() behind “a small source-code blocklist”, CVE-2026-57138 says.
The record, published 15 September at 9.9 out of 10, covers versions from 1.4.0 until 1.7.2, with the sandbox’s process and require properties shadowed rather than removed. The escape is the one every JavaScript sandbox built this way has had: “({}).constructor.constructor” recovers the real Function constructor, which recovers process and process.mainModule.require, which reaches the filesystem and subprocess APIs “despite the advertised sandbox”. CVE-2026-57141, at 9.8 out of 10, records a second route to the same place, Function(‘return this’)() for the global object and a child_process module name assembled at runtime so the regex never sees it.
Two records at 8.8 describe the shell side. CommandValidator “validates only the first whitespace-delimited executable against allowedCommands” and then hands the whole string to sh -c, and the shell() helper does the same before child_process.exec, so a string that begins with an allowed read-only command carries any second command the shell will parse.
All four are fixed in 1.7.2, and the input in every case is what a model wrote, which is the point of the tool.
What it changes On PraisonAI’s TypeScript package, upgrade to 1.7.2. Anywhere else, if a tool runs model-written code inside a language that has a constructor chain, a blocklist is not a boundary; use a process or a VM with no host handles.
Primary source read
NVD record, CVE-2026-57138 NVD record, CVE-2026-57141 NVD record, CVE-2026-57136, CommandValidator NVD record, CVE-2026-57133, shell() helper