n8n Edit Fields (Set) Node Prototype Pollution Denial of Service
An authenticated n8n user can name a workflow field '__proto__.hasOwnProperty' in the Edit Fields node, corrupting a shared global in the main Node.js process and crashing authentication for every…
The problem
The Edit Fields (Set) node in n8n accepted arbitrary dot-notation field names and wrote them to output objects using an unrestricted path-setter (equivalent to lodash _.set). No key-segment validation was applied.
Because __proto__ is a valid path segment in such setters, a field named __proto__.hasOwnProperty (or any other inherited built-in) writes directly onto Object.prototype. That global mutation persists for the entire lifetime of the Node.js process. The poisoned property sat on the request-authentication code path, causing every subsequent authenticated request to throw, producing an instance-wide denial of service until the process was restarted.
Proof of concept
A working proof-of-concept for this issue in n8n, with the exact payload below.
// In the Edit Fields (Set) node, add a new field with:
// Field Name: __proto__.hasOwnProperty
// Field Value: 1 (any truthy value)
//
// When the workflow runs, the Set node internally calls something like:
// _.set(outputItem, '__proto__.hasOwnProperty', 1)
// This writes onto Object.prototype:
// Object.prototype.hasOwnProperty = 1
// All subsequent calls to obj.hasOwnProperty(...) in the process throw
// a TypeError instead of returning a boolean, breaking the auth path.
// Equivalent JS that demonstrates the primitive:
const _ = require('lodash'); // or n8n's own dot-notation setter
const obj = {};
_.set(obj, '__proto__.hasOwnProperty', 1);
console.log(({}).hasOwnProperty('x')); // TypeError: hasOwnProperty is not a functionThe root cause is CWE-1321: the dot-notation path-setter split the field name on . and blindly walked the prototype chain, so the segment __proto__ resolved to Object.prototype rather than a plain object key. The patch (commit f69dfc6) added a denylist or safe-key guard that rejects any path segment equal to __proto__, constructor, or prototype before the setter runs, preventing traversal up the prototype chain.
The gadget that turned this into a DoS was n8n's authentication middleware reading obj.hasOwnProperty as a function on every request. Once Object.prototype.hasOwnProperty was overwritten with a non-function scalar, that call threw a TypeError instance-wide, not just in the offending workflow.
The fix
Upgrade to n8n 1.123.67, 2.31.5, or 2.32.1. The patch blocks any dot-notation path segment that matches __proto__, constructor, or prototype in the Edit Fields (Set) node before the path-setter is invoked. If an immediate upgrade is not possible: restrict workflow creation and execution to fully trusted users, and monitor for unexpected process-wide HTTP 500 errors, restarting the process promptly if they occur.
Reported by csuermann (n8n Security Team).
Related research
- highCVE-2026-59206CVE-2026-59206: n8n Prototype Pollution via Workflow Credentials
- highCVE-2026-65016: n8n SSO Instance-Role Provisioning Privilege Escalation to Instance Owner
- highCVE-2026-59209CVE-2026-59209: n8n Shared Credential Header Leak via HTTP Request Pagination Expression
- highCVE-2026-59207CVE-2026-59207: n8n AI Agents MCP Connector Allowed HTTP Request Domains Bypass