The vulnerability is a Remote Code Execution (RCE) in the n8n workflow expression evaluation system. The root cause is insufficient sandboxing of user-provided expressions, which allows an authenticated attacker to execute arbitrary code on the server.
The primary flaw is that function expressions within the evaluated code could gain access to the Node.js global this object. In a Node.js environment, the global this provides access to the process object, which can be abused to execute system commands (e.g., via process.mainModule.require('child_process').execSync(...)).
The analysis of the patches reveals two key areas that were addressed:
-
Lack of this Context Sanitization: The main expression evaluator, an instance of the Tournament class, was not configured to sanitize the this context of function expressions. The patch introduces a new ASTBeforeHook called FunctionThisSanitizer. This hook traverses the Abstract Syntax Tree (AST) of the user's expression and rewrites all function expressions and calls to explicitly bind their this context to a safe, empty object ({ process: {} }). This prevents the functions from accessing the real process object. The function Tournament.execute is the entry point for this vulnerable evaluation process.
-
Incomplete Property Blacklist: As a secondary defense mechanism, the isSafeObjectProperty function maintains a blacklist of properties that should not be accessible. The vulnerable version of this function was missing several properties related to Node.js internals (mainModule, binding, _load) that could be leveraged for RCE. The patch adds these to the blacklist, strengthening the sandbox against property-based attacks.
Therefore, the vulnerable functions are Tournament.execute, which performs the unsanitized evaluation, and isSafeObjectProperty, which provided an incomplete security check in the vulnerable versions.