High

n8n Workflow Expression Sandbox Escape to OS Execution

n8n lets workflows evaluate expressions in a restricted JavaScript sandbox. This rule watches for that sandbox being broken out of so the attacker's code runs as a real OS process, then talks to the internet or steals credentials.

How the attack works

An attacker crafts a workflow expression containing a known sandbox-escape idiom, such as reaching into constructor.constructor, process.mainModule.require, vm.runInNewContext, or a Function('return ...') trick. n8n's runtime process evaluates this expression and, instead of staying inside the sandbox, spawns an OS-level interpreter or shell command as a child process. That child process then does something a workflow expression should never be able to do: connect out to a public (non-internal) host, or read a credential file on disk. The detection follows the n8n process and its descendants up to three levels deep and only flags the chain when the suspicious spawn is paired with one of these follow-on signs.

Netzilo detection

Netzilo reports this behaviour when it is observed.

Signature ID
3f7c9a1e-5b42-4d8e-9c07-1a6f2b83d4e5
Severity
High

Why it matters

A successful escape gives an attacker arbitrary command execution on the server hosting n8n, with the ability to exfiltrate data or read stored credentials, effectively turning a workflow automation tool into a foothold for full host compromise.

What you can do

  • Restrict who can create or edit workflows in n8n, since expression evaluation is the entry point for this attack.
  • Run n8n in a container or sandboxed host with no unnecessary outbound network access, so a spawned process cannot reach public endpoints.
  • Keep credential files and secrets out of reach of the n8n process user, or use a secrets manager instead of local files.
  • Review use of the built-in "Execute Command" node and restrict it to trusted operators, since legitimate use of that node can resemble the early stage of this attack.

Known benign look-alikes

  • n8n "Execute Command" node used deliberately by an operator to run shell or python jobs. A bare interpreter spawn is never reported on its own; the rule additionally requires a dynamic-code escape idiom, public egress by that child, or a credential-file read by that child.
  • Community-node or npm install activity during n8n startup, which spawns sh and fetches packages. Reported only if the spawned child also reaches a public endpoint or reads a credential file inside the 5-minute window.
  • Container entrypoint / supervisor wrappers around n8n (sh -c "n8n start"), and backup jobs invoking scp/curl to internal (ZTNA/private) destinations, which do not satisfy the public-egress stage.
  • Deliberate red-team validation of the n8n expression sandbox, or a security engineer reproducing the CVE in a lab instance.
  • CI runners that build n8n from source and execute node --eval during tests; the n8n runtime process is the anchor, so build tooling outside its process tree is not evaluated.

References