Vulnerability Analysis

CVE-2026-21858 (Ni8mare): Unauthenticated RCE in n8n Workflow Automation & How to Fix It

Executive Summary

CVE-2026-21858, dubbed "Ni8mare" by researchers at Cyera Research Labs, is a CVSS 10.0 unauthenticated Remote Code Execution (RCE) vulnerability in the n8n open-source workflow automation platform. The flaw stems from a content-type confusion bug in n8n's webhook request handling that allows an unauthenticated attacker to read arbitrary local files, forge administrator session cookies, and ultimately execute arbitrary OS commands on the underlying host. Organizations running self-hosted n8n instances prior to version 1.121.0 should treat this as an emergency patch.


1. What Is This Vulnerability?

n8n is a popular open-source, self-hostable workflow automation platform — widely adopted by teams building AI pipelines, data integrations, and internal tooling. It processes webhooks and file uploads as part of its core node-based workflow engine.

The root cause is deceptively simple: certain webhook handlers in n8n access req.body.files without first verifying that the incoming request's Content-Type is multipart/form-data. This means an attacker can craft an application/json POST request that includes a files object pointing to arbitrary file paths on the local server — and n8n will treat those paths as if they were user-uploaded files.

Attack Chain (Three Stages)

Stage 1 — Arbitrary File Read

An attacker sends a specially crafted JSON payload to an exposed webhook endpoint with a files key containing paths to sensitive local files. Because the handler does not validate the content type, it reads and returns the contents of those files to the attacker. No credentials or session tokens are required.

POST /webhook/some-endpoint HTTP/1.1
Host: n8n.victim.internal
Content-Type: application/json

{
  "files": [
    { "path": "/home/node/.n8n/config" },
    { "path": "/home/node/.n8n/database.sqlite" }
  ]
}

Stage 2 — Authentication Bypass / Session Forgery

The two files retrieved in Stage 1 contain everything needed to impersonate any user on the instance:

  • /home/node/.n8n/config — contains the instance's unique encryptionKey / JWT signing secret
  • /home/node/.n8n/database.sqlite — contains the full user table, including administrator accounts, email addresses, and password hashes

With the signing secret and an admin user ID in hand, the attacker reconstructs a valid n8n-auth session cookie. The platform accepts this cookie as a legitimate administrator session, granting full access to the n8n UI and API.

Stage 3 — Remote Code Execution

n8n's built-in Execute Command workflow node runs arbitrary shell commands on the host as the n8n service user. An authenticated attacker creates a new workflow containing an Execute Command node, triggers it, and achieves OS-level code execution — all without ever having had a valid account.

Attack Vector

The attack is network-accessible and requires no authentication. Any n8n webhook URL that is publicly reachable (or reachable from within a compromised network segment) can serve as the entry point. Exploitation is low-complexity and requires no user interaction, earning the vulnerability its maximum CVSS score of 10.0.

Real-World Impact

Within weeks of disclosure in January 2026, security researchers at Censys observed active scanning of internet-facing n8n instances probing for exploitable webhook endpoints. Organizations using n8n to orchestrate AI model integrations, cloud services, or internal data pipelines face the risk of full host compromise, credential exfiltration, supply chain poisoning via tampered workflows, and lateral movement into connected downstream services.


2. Who Is Affected?

Component Vulnerable Versions Safe Version
n8n (self-hosted) < 1.121.0 ≥ 1.121.0
n8n (npm package) n8n@<1.121.0 n8n@1.121.0
n8n (Docker image) n8nio/n8n:<1.121.0 n8nio/n8n:1.121.0

Who is most at risk:

  • Teams running self-hosted n8n instances with webhook nodes exposed to the internet or untrusted internal networks
  • Organizations that have not isolated n8n behind a VPN or authentication proxy
  • Deployments running n8n as a privileged service user (root or with broad file system access)
  • CI/CD pipelines and AI agent frameworks that use n8n as an orchestration layer

n8n Cloud (managed SaaS) was patched directly by the n8n team and is not affected for cloud customers.


3. How to Detect It (Testing)

Manual Testing Steps

  1. Identify webhook endpoints: Review your n8n instance for active webhook trigger nodes. Note the /webhook/ paths configured in your active workflows.
  2. Send a content-type confusion probe: Using curl or Burp Suite, submit a POST request to a webhook endpoint with Content-Type: application/json and a files array pointing to a known safe path (e.g., /etc/hostname):
    curl -s -X POST https://your-n8n-instance/webhook/test-endpoint \
      -H "Content-Type: application/json" \
      -d '{"files": [{"path": "/etc/hostname"}]}'
    
  3. Evaluate the response: If the response body contains the content of /etc/hostname (or a filename is echoed back), the instance is vulnerable. A patched instance will reject the malformed request with a 400 error or ignore the files parameter entirely.
  4. Check the n8n version: Log into the n8n UI and navigate to Settings → About. Confirm the version is 1.121.0 or higher.

Automated Scanning

Tool: Nuclei (Project Discovery)

A community-contributed Nuclei template for CVE-2026-21858 is available in the nuclei-templates repository:

nuclei -u https://your-n8n-instance \
  -t cves/2026/CVE-2026-21858.yaml \
  -severity critical

Tool: Grype / Trivy (Container Image Scanning)

If n8n is deployed as a Docker container, scan the image for the vulnerable package version:

# Grype
grype n8nio/n8n:latest

# Trivy
trivy image n8nio/n8n:latest --severity CRITICAL

Both tools will flag n8n < 1.121.0 as containing CVE-2026-21858.

Tool: Shodan / Censys (Exposure Assessment)

Check whether your n8n instance is internet-accessible:

shodan search "n8n" port:5678 org:"Your Org ASN"

If your instance appears in results, it is likely reachable by external attackers.

Code Review Checklist

  • Search webhook handler code for req.body.files — verify Content-Type is validated before access
  • Confirm that file-handling logic enforces multipart/form-data as a precondition
  • Verify that local file paths cannot be injected through user-controlled JSON fields
  • Check that Execute Command nodes in active workflows are restricted to authorized users only
  • Audit workflow definitions for unexpected Execute Command, HTTP Request, or Code nodes added after your last known-good backup

4. How to Fix It (Mitigation)

Step-by-Step Remediation

Option A: Upgrade n8n (Recommended)

  1. Back up your current instance before upgrading, including the .n8n data directory and any custom workflow exports.
  2. Upgrade via npm:
    npm update -g n8n
    # or for a specific version
    npm install -g n8n@1.121.0
    
  3. Upgrade via Docker:
    docker pull n8nio/n8n:1.121.0
    docker stop n8n && docker rm n8n
    docker run -d --name n8n \
      -p 5678:5678 \
      -v ~/.n8n:/home/node/.n8n \
      n8nio/n8n:1.121.0
    
  4. Verify the upgrade: Navigate to Settings → About in the n8n UI and confirm version 1.121.0 or higher.
  5. Rotate secrets: After patching, rotate the N8N_ENCRYPTION_KEY environment variable and invalidate all active sessions. Any session cookies forged before the patch may still be valid until the encryption key is rotated.

Option B: Restrict Network Access (Interim Workaround)

If an immediate upgrade is not feasible, restrict access as follows:

  1. Place n8n behind a reverse proxy (nginx, Caddy, Traefik) with authentication (Basic Auth or OAuth2 proxy) applied at the proxy layer.
  2. Block public access to n8n's port (default: 5678) at the firewall or security group level.
  3. Restrict webhook access to known IP ranges using firewall rules.

⚠️ This is a mitigation, not a fix. Network restriction does not address the underlying vulnerability. Upgrade as soon as possible.

Code Fix Example

The fix in n8n 1.121.0 adds an explicit content-type check before accessing req.body.files in the webhook handler:

// BEFORE (vulnerable)
async handleWebhookRequest(req: Request, res: Response) {
  const files = req.body.files; // ❌ No content-type check
  // ... process files
}

// AFTER (patched)
async handleWebhookRequest(req: Request, res: Response) {
  if (!req.is('multipart/form-data')) {
    // ✅ Only process files for multipart requests
    return res.status(400).json({ error: 'Invalid content type for file upload' });
  }
  const files = req.files; // Safe: populated only for valid multipart requests
  // ... process files
}

Configuration Hardening

Beyond patching, apply these hardening measures to your n8n deployment:

# Run n8n as a non-root user (already default in Docker, verify in custom installs)
# Restrict n8n data directory permissions
chmod 700 ~/.n8n
chmod 600 ~/.n8n/config
chmod 600 ~/.n8n/database.sqlite

# Set a strong encryption key via environment variable (not in config file)
export N8N_ENCRYPTION_KEY="$(openssl rand -base64 32)"

# Disable public webhook access if webhooks are only used internally
# Set N8N_HOST to bind only to localhost when behind a reverse proxy
export N8N_HOST=127.0.0.1

5. How to Test the Fix (Validation)

Regression Test Scenarios

  • Scenario A: Submit the content-type confusion payload against the patched instance — expect HTTP 400 and no file content in response.
  • Scenario B: Confirm legitimate multipart file uploads through workflows still function correctly after upgrading.
  • Scenario C: Verify that session cookies from pre-patch sessions are invalidated after rotating the encryption key.

Security Test Cases

Test Case 1: Verify the content-type confusion is blocked

  • Precondition: n8n upgraded to 1.121.0 or later, with an active webhook trigger workflow running
  • Steps:
    curl -s -X POST https://your-n8n-instance/webhook/your-path \
      -H "Content-Type: application/json" \
      -d '{"files": [{"path": "/etc/passwd"}]}'
    
  • Expected Result: Response is HTTP 400 or HTTP 200 with no file content; /etc/passwd contents do NOT appear in the response body.

Test Case 2: Verify legitimate webhooks still function

  • Precondition: Patched instance with a webhook-triggered workflow that processes JSON data
  • Steps: Send a normal JSON payload to the webhook endpoint
  • Expected Result: Workflow triggers and executes normally; no regression in functionality.

Test Case 3: Session invalidation after key rotation

  • Precondition: N8N_ENCRYPTION_KEY rotated post-patch; old session cookie captured before rotation
  • Steps: Attempt to use the pre-rotation cookie to access the n8n API
  • Expected Result: Request returns HTTP 401; old session is rejected.

Automated Tests

#!/bin/bash
# n8n CVE-2026-21858 patch validation script
N8N_URL="https://your-n8n-instance"
WEBHOOK_PATH="/webhook/test"

echo "[*] Testing CVE-2026-21858 patch..."

RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${N8N_URL}${WEBHOOK_PATH}" \
  -H "Content-Type: application/json" \
  -d '{"files": [{"path": "/etc/passwd"}]}')

HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | head -1)

if echo "$BODY" | grep -q "root:"; then
  echo "[FAIL] VULNERABLE: /etc/passwd contents returned. Patch not applied!"
  exit 1
else
  echo "[PASS] File contents not returned (HTTP $HTTP_CODE). Patch appears effective."
  exit 0
fi

6. Prevention & Hardening

Best Practices

  • Keep n8n updated: Subscribe to the n8n security advisories on GitHub and apply patches promptly. Given n8n's rapid release cadence, pin to the latest stable minor release.
  • Never expose n8n directly to the internet: Always place n8n behind an authenticated reverse proxy. Use OAuth2 Proxy, Authelia, or Cloudflare Access to enforce identity verification before any request reaches the n8n application layer.
  • Restrict Execute Command nodes: Use n8n's built-in role-based access controls to limit which users can create or modify workflows containing Execute Command, Code, or HTTP Request nodes. Consider disabling the Execute Command node entirely if your use case does not require it (EXECUTIONS_PROCESS=own).
  • Apply the principle of least privilege: Run n8n as a dedicated non-root service account. Mount only necessary directories. Avoid giving n8n access to credential stores, cloud provider metadata endpoints, or sensitive configuration files.
  • Rotate secrets regularly: Set N8N_ENCRYPTION_KEY via environment variable (not config file) and rotate it quarterly or after any suspected compromise.
  • Audit workflows regularly: Review active workflow definitions on a regular schedule for unexpected nodes, especially Execute Command, HTTP Request to internal endpoints, or Code nodes added outside of your normal change management process.

Monitoring & Detection

Set up alerts for the following indicators of compromise (IoCs) related to this vulnerability:

# Watch for suspicious file reads in n8n logs
grep -E "\/etc\/passwd|\/etc\/shadow|\.n8n\/config|database\.sqlite" /var/log/n8n/*.log

# Monitor for unexpected child processes spawned by n8n
# (Linux: auditd rule for process ancestry)
auditctl -a always,exit -F arch=b64 -S execve -F ppid=$(pgrep -f "node.*n8n") -k n8n_exec

# Alert on unexpected outbound connections from the n8n service user
iptables -I OUTPUT -m owner --uid-owner node -j LOG --log-prefix "n8n-outbound: "

In a SIEM, create correlation rules that alert when:

  1. Any n8n webhook endpoint returns a response larger than expected for your typical workflow payloads (potential file read exfiltration)
  2. The n8n service process spawns a child process (potential Execute Command node abuse)
  3. A new workflow is created by an account that has not previously created workflows (potential attacker-forged session)

References

Latest from the blog

See all →