Listen to this Post
n8n uses expressions for workflow automation.
Expressions are compiled and sanitized before evaluation.
The sanitizer is intended to block dangerous JavaScript constructs.
It uses a dynamically scoped this binding during resolution.
A class field named __sanitizer can shadow or rebind that reference.
When the expression compiler resolves the sanitizer through this, it may call the attacker-controlled class field.
That rebound value can point to the Function constructor.
The Function constructor creates JavaScript functions from strings.
Once reached, it bypasses the intended expression sandbox.
On the backend, this affects the n8n process.
Any user allowed to author an expression can run code with n8n process privileges.
In the editor preview, the risk is different.
A member’s expression can run as JavaScript in the session of whoever opens the workflow.
This can expose editor sessions and workflow context.
The root cause is not expression syntax alone.
It is the sanitizer lookup path and class-field rebinding.
The patch rejects reserved class-member names.
This prevents __sanitizer from being used as a class field.
Affected versions include < 1.123.76.
Also >= 2.38.0, < 2.38.2.
Also >= 2.0.0, < 2.37.7.
Patched versions are 1.123.76, 2.38.2, and 2.37.7.
Administrators should upgrade to one of these versions or later.
If upgrade is not immediate, use N8N_EXPRESSION_ENGINE=vm.
That workaround is temporary and does not fully remediate risk.
The advisory is GitHub Reviewed and published Sep 2, 2026.
It was updated Sep 10, 2026.
High severity is assigned.
No CVE ID is provided in the source .
DailyCVE Form:
Platform: n8n
Version: Multiple n8n versions
Vulnerability: Expression sandbox escape
Severity: High
date: Sep 2 2026
Prediction: Sep 10 2026
What Undercode Say:
Analytics:
n8n --version
npm view n8n versions --json | grep -E '1.123.76|2.37.7|2.38.2'
docker exec -it n8n n8n --version
grep -R "__sanitizer" ./node_modules/n8n | head
// Patch check: reject reserved class-member names
const reservedClassMembers = new Set(["__sanitizer"]);
function assertAllowedClassMember(name) {
if (reservedClassMembers.has(name)) {
throw new Error("Reserved class member name");
}
}
How Exploit: (Educational Purposes!)
1. Expression author defines class field named __sanitizer. 2. Sanitizer lookup resolves through dynamic this. 3. Rebound value reaches Function constructor. 4. Code execution occurs in n8n process or editor session.
Protection: from this CVE
npm install -g [email protected] npm install -g [email protected] npm install -g [email protected]
export N8N_EXPRESSION_ENGINE=vm
services: n8n: image: n8nio/n8n:1.123.76 environment: - N8N_EXPRESSION_ENGINE=vm
const reservedClassMembers = new Set(["__sanitizer"]);
function assertAllowedClassMember(name) {
if (reservedClassMembers.has(name)) {
throw new Error("Reserved class member name");
}
}
Impact:
Backend: code execution as n8n process. Editor: JavaScript in opener session. Authors: sandbox escape via expression. Remediation: upgrade to patched versions.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

