Critical

PraisonAI codeMode JS Sandbox Escape RCE via new Function/with() (GHSA-p69m-4f92-2v84)

PraisonAI, an AI agent framework, includes a feature that lets an LLM write and run JavaScript through a 'sandbox' meant to contain it. That sandbox is trivially broken, letting an attacker who can influence the LLM's generated code execute arbitrary operating system commands on the host.

How the attack works

PraisonAI's codeMode tool runs LLM-produced code using new Function() combined with a with() block, intending to limit what the code can touch. The only protection is a regex blocklist that scans for dangerous keywords in the code text. An attacker crafts code that uses tricks like Function('return this') or (function(){}).constructor('return process') to recover the real JavaScript global object, escaping the with() scope entirely. From there they rebuild the string 'child_process' by splitting it (e.g. 'child_' + 'process') to dodge the blocklist, then call execSync or exec to run arbitrary shell commands.

Netzilo detection

Netzilo reports this behaviour when it is observed.

Signature ID
f5b14596-737f-4c88-9b13-2239810f1b68
Severity
Critical

Why it matters

An attacker who can get their code accepted as LLM output in a PraisonAI agent gains full command execution on the server running the agent, which typically means complete compromise of that host and anything reachable from it.

What you can do

  • Update PraisonAI past version 1.7.1 or disable the codeMode tool until a fixed release is confirmed available.
  • Do not rely on regex/keyword blocklists to contain LLM-generated code execution; treat any 'sandbox' built on new Function/with() as unsafe.
  • Run any LLM code-execution feature in a real isolation boundary such as a separate container, VM, or restricted subprocess with no access to child_process, filesystem, or network.
  • Audit logs for code patterns like Function('return this'), constructor('return process'), or split string reconstruction of 'child_process' in tool inputs/outputs.

Known benign look-alikes

  • Legitimate JS that calls child_process.execSync via a normal `require('child_process')` import in trusted server code, not inside a codeMode/sandbox-bypass chain.
  • Documentation or test fixtures discussing `new Function` or `with(){}` scoping without the global-recovery + child_process exploit chain.
  • Code that uses `(function(){}).constructor` only for legitimate function-type checks without invoking `'return process'`/`'return this'` or reaching child_process.

References

Related threats