From Schema Name to RCE: Dissecting CVE-2026-33696 in n8n

Translated by a model; the original is in Russian.

· Security
Researcher Simon Köck describes how the innocuous “Custom Fields” option in the GSuiteAdmin node of the n8n automation platform turns into remote code execution through prototype pollution.

cover.svg

Security researcher Simon Köck has published a breakdown of CVE-2026-33696, a vulnerability in the popular workflow automation platform n8n. The flaw is a classic — prototype pollution — but the path from there to full control over the server turned out to be almost textbook.

A single line of code

Köck went through the codebase looking for places where a user-supplied string ends up as a key on an ordinary object without any check for dangerous names like __proto__, constructor, and prototype. The GSuiteAdmin node jumped out right away. It has a “Custom Fields” section for creating and updating users, where the schema name, the field name, and the value are all taken straight from the workflow configuration — that is, fully controlled by an attacker with editor privileges.

The schema name is used as a dynamic key:

customSchemas[schemaName] ??= {};
(customSchemas[schemaName])[fieldName] = value;

If you set schemaName to __proto__, the write lands right on Object.prototype. The entire vulnerability fits into these two lines.

From pollution to code execution

The pollution alone is already devastating: when TypeORM iterates over properties with for...in, it starts running into the extra fields and throws an error on every database query. The n8n interface hangs, all executions fail, and the only way to bring the system back to life is a full restart.

But Köck went further and assembled a chain all the way to RCE. The simple-git library creates an empty environment object {}, which inherits the properties of the polluted prototype. When spawn() is called, Node.js carries the inherited properties over into the child process too. And git, on encountering an SSH-like URL, runs the contents of the GIT_SSH_COMMAND variable as a shell command. It's enough to pollute Object.prototype.GIT_SSH_COMMAND — and an arbitrary command executes under the n8n process.

The full attack looks like this: webhook → GSuiteAdmin node (pollution) → Git node (execution). A single HTTP request kicks off the whole chain. The GSuiteAdmin node does crash when it calls the Google API, but that no longer matters — the pollution happens before the request is sent.

Impact and the fix

Every deployment variant is affected — self-hosted, worker mode, and cloud. The attacker gets code execution under the n8n process, and with it access to the encryption key for all stored credentials, plus the ability to stage a complete denial of service.

The cure is trivial: just reject dangerous property names or create the object via Object.create(null). The irony is that the n8n codebase already has a deepMerge utility with protection against prototype pollution — the GSuiteAdmin node simply didn't use it.

The report was sent to the n8n security team on February 26, 2025, and the advisory and CVE were published on March 25, 2025.


Source: Lobsters

Comments

Sign in, to comment.

  • No comments yet.