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.jsprocessobject - 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:
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:
Step-by-step breakdown:
(()=>Reflect)()-- Arrow function captures realReflect, bypasses polyfill(()=>process)()-- Arrow function captures realprocess, bypasses polyfillR.get(p, 'getBuiltinModule')--Reflect.getbypasses MemberExpression denylist('child_process').execSync('id')-- Loadschild_processmodule, 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.envfor 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:
Vulnerable ranges: <2.31.5 OR >=2.32.0 <2.32.1
Mitigation & Patching
Immediate Action: Update Now
Verify you're on 2.31.5 or 2.32.1 (or later).
Short-term Mitigations (if immediate update impossible)
- Restrict workflow editing to fully trusted users only
- Set
N8N_EXPRESSION_ENGINE=vm-- uses Node.jsvmmodule instead ofnew Function(incomplete mitigation per advisory) - Audit recent workflows for unexpected arrow functions or obfuscated JavaScript
Post-Exploitation Cleanup (if you ran affected version with untrusted editors)
- Rotate
N8N_ENCRYPTION_KEYand all stored credentials - Hunt for suspicious child processes -- shells, PowerShell,
curl,wgetspawned by n8n/Node.js - Review workflow execution logs for anomalous expressions
- Check cloud metadata endpoints for unauthorized access
Detection
Workflow-Level Indicators
- Arrow function expressions in Set/Function/Expression nodes:
() => ... Reflect.getorReflect.ownKeysusage- 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.