/00 — boot sequence

Hello.

Article

n8n Sandbox Escape: Authenticated RCE via Arrow Function Bypass (GHSA-gv7g-jm28-cr3m)

July 27, 2026•5 min read
security n8n rce vulnerability workflow-automation sandbox-escape

Security researchers at Security Joes discovered a critical sandbox escape in n8n, the popular open-source workflow automation platform with over 200,000 GitHub stars. The vulnerability allows any authenticated user with workflow editing permissions to execute arbitrary commands on the host server as the n8n process user.

Background

n8n (pronounced "n-eight-n") has become a cornerstone of modern DevOps and AI automation pipelines. Developers use it to connect APIs, databases, LLMs, and cloud services through a visual workflow editor. At the heart of every workflow sits an expression evaluator -- a JavaScript sandbox that lets users write dynamic logic like ={{ $input.first().json.name }} directly inside node parameters.

That sandbox is the attack surface. Since 2025, n8n has faced a recurring pattern of sandbox escapes:

  • CVE-2025-68613 -- (function(){ return this })() leaked the real Node.js process object
  • CVE-2026-25049 -- Template literal destructuring bypass: { [\constr${'uct'}o]: c }
  • CVE-2026-27577 (CVSS 9.4) -- Spread element bypass: {...process} was never rewritten

Each time, n8n patched the specific vector. Each time, researchers found another way in.

Vulnerability Details

CVE ID: Awaiting assignment (tracked as GHSA-gv7g-jm28-cr3m)
CVSS 4.0 Score: 8.7 (High) -- n8n's self-assessment; researchers estimate ~9.4 Critical
Affected Versions: <2.31.5 and >=2.32.0, <2.32.1
Fixed Versions: 2.31.5 and 2.32.1
Attack Vector: Network (authenticated workflow editor)
Privileges Required: Low (workflow create/edit permission)
User Interaction: None

The Root Cause: Two Independent Rewriter Blind Spots

The expression sandbox lives in packages/workflow/src/expression-sandboxing.ts and @n8n/tournament's VariablePolyfill.ts. The jsVariablePolyfill function rewrites free identifiers (process, Reflect, globalThis) to safe data-context lookups -- but only for specific AST parent types.

Blind Spot 1: Arrow Function Bodies
When the parent AST node is ArrowFunctionExpression, the switch statement hits an explicit break (a no-op). Identifiers in the signature or body of arrow functions are never polyfilled. This means:

javascript

Blind Spot 2: Reflect.get with String Arguments
The property denylist (getBuiltinModule, binding, dlopen, etc.) is enforced via visitMemberExpression, which inspects static property names. Reflect.get(obj, 'getBuiltinModule') passes the property as a string argument -- not a static property access -- so the denylist never fires.

The Exploit Chain

Combining both gaps yields a complete RCE payload:

javascript

Step-by-step breakdown:

  1. (()=>Reflect)() -- Arrow function captures real Reflect, bypasses polyfill
  2. (()=>process)() -- Arrow function captures real process, bypasses polyfill
  3. R.get(p, 'getBuiltinModule') -- Reflect.get bypasses MemberExpression denylist
  4. ('child_process').execSync('id') -- Loads child_process module, executes OS command

Security Joes verified this against n8n 2.30.4 (released after the CVE-2026-27577 patch) using both the published n8n-workflow package and a live npx n8n instance.

Impact Assessment

Any authenticated user with workflow create/edit permissions achieves host-level RCE as the n8n process user. In cloud-hosted environments this means:

  • Reading process.env for API keys, OAuth tokens, N8N_ENCRYPTION_KEY
  • Decrypting every stored credential in n8n's vault
  • Lateral movement to internal services, databases, and cloud metadata endpoints reachable from the n8n host
  • Persistence via modified workflows or stolen encryption keys

The vulnerability requires valid credentials (PR:L) but no user interaction. A compromised workflow editor account (via phishing, credential stuffing, or insider threat) is sufficient.

Affected Systems

Self-hosted n8n instances running affected versions are vulnerable. n8n Cloud status is unclear -- the advisory does not specify whether the managed service was impacted.

Check your version:

bash

Vulnerable ranges: <2.31.5 OR >=2.32.0 <2.32.1

Mitigation & Patching

Immediate Action: Update Now

bash

Verify you're on 2.31.5 or 2.32.1 (or later).

Short-term Mitigations (if immediate update impossible)

  1. Restrict workflow editing to fully trusted users only
  2. Set N8N_EXPRESSION_ENGINE=vm -- uses Node.js vm module instead of new Function (incomplete mitigation per advisory)
  3. Audit recent workflows for unexpected arrow functions or obfuscated JavaScript

Post-Exploitation Cleanup (if you ran affected version with untrusted editors)

  1. Rotate N8N_ENCRYPTION_KEY and all stored credentials
  2. Hunt for suspicious child processes -- shells, PowerShell, curl, wget spawned by n8n/Node.js
  3. Review workflow execution logs for anomalous expressions
  4. Check cloud metadata endpoints for unauthorized access

Detection

Workflow-Level Indicators

  • Arrow function expressions in Set/Function/Expression nodes: () => ...
  • Reflect.get or Reflect.ownKeys usage
  • Obfuscated strings: 'getBuiltinModule', 'child_process'
  • Unexpected external network calls from workflow executions

Host-Level Indicators

  • Shell/PowerShell/curl/wget processes with n8n/Node.js as parent
  • Unusual outbound connections from n8n host
  • Modified workflow files with new expressions

Timeline

  • July 14, 2026 -- Sandbox escape residual identified on n8n HEAD and 2.30.4
  • July 15, 2026 -- Reported via n8n Vulnerability Disclosure Program
  • July 15, 2026 -- Report ID issued: th_01KXJHJJ3WEK3R84HHHHF4F50K
  • July 22, 2026 -- n8n confirmed: vulnerability accepted, fix deployed, CVE awaiting assignment
  • July 27, 2026 -- Public advisory published

What Made This Different

Most n8n sandbox research targets one gadget at a time. This bypass needed two independent rewriter blind spots working together: the arrow-function polyfill gap (structural) and the Reflect.get string-argument denylist gap (semantic). Neither alone is sufficient. Neither was covered by tests.

The fix for CVE-2026-27577 added 15 lines to visitSpreadElement. It closed the spread vector completely. But it didn't ask a broader question: what other AST parent types does the polyfill skip? Answering that question is what found this bypass.

Responsible Disclosure

Security Joes reported directly to n8n's VDP before publishing anything. No live instances were tested. All research was conducted on a local self-hosted instance running the published npm package. They waited for confirmation and fix before writing this.

Fix

n8n has confirmed the fix is deployed. If you are self-hosting, update immediately. As a short-term mitigation: set N8N_EXPRESSION_ENGINE=vm or restrict workflow creation to fully trusted users only. Rotate N8N_ENCRYPTION_KEY and all stored credentials if you were running an affected version with untrusted workflow editors.


Sources:
Security Joes: Breaking the Sandbox Again
The Hacker News: n8n Sandbox Escape
n8n Security Advisory GHSA-gv7g-jm28-cr3m

Automated Transmission

This entry was synthesized and populated dynamically using native API integrations.

Resources & Links