n8n is open-source and self-hostable. That's not in question. What's worth examining in real technical detail is what keeping a self-hosted instance genuinely secure and operational actually requires on an ongoing basis — not as a hypothetical, but against the platform's real, publicly-tracked 2026 disclosure history and its own documented operational failure modes.
2026 was a genuinely bad year for unpatched n8n instances
Between January and June 2026, security researchers disclosed multiple critical vulnerabilities in n8n, several rated the maximum possible CVSS score of 10.0. This isn't a hypothetical risk category — it's a documented pattern across two full quarters.
Remote code execution via expression injection in n8n's workflow expression evaluator. An authenticated user's crafted expression can escape the intended sandbox by reaching JavaScript's global this, from there reaching the Node.js process object, and executing arbitrary OS-level commands with the privileges of the n8n process itself. Listed in CISA's Known Exploited Vulnerabilities catalog, with an EPSS score of 99.9% — among the highest exploitation-likelihood scores a CVE can carry, and public proof-of-concept code is available. Affects versions 0.211.0 up to, but not including, 1.120.4, 1.121.1, and 1.122.0. Fixed in all three.
Unauthenticated remote code execution via a Content-Type confusion flaw in n8n's webhook and form-handling logic. No credentials required — a crafted HTTP request to a public webhook endpoint can read arbitrary files, forge admin sessions, and execute code. Affects all versions up to and including 1.65.0 (later re-scoped to versions prior to 1.121.0). Fixed in 1.121.0, released November 18, 2025.
Authenticated RCE via unrestricted upload of a dangerous file type — an authenticated user can cause the n8n service to execute untrusted code, leading to full instance compromise. Affects versions 0.123.0 up to 1.121.3. Fixed in 1.121.3.
Sandbox bypass allowing any authenticated user with workflow create/modify permission to execute arbitrary commands on the host system. Fixed in 2.0.0.
Unauthenticated RCE exploitable via public webhooks — a single line of injected JavaScript using destructuring syntax runs arbitrary system commands. Fixed in 1.123.17 / 2.5.2.
A deserialization flaw capable of extracting conversation histories and stored secrets from LangChain-integrated workflows.
RCE via the Git node — workflow actions could influence Git configuration (specifically core.hooksPath) and trigger hook execution. Affects versions 0.123.1 through 1.119.1. Fixed in 1.119.2.
Symlink traversal in the Read/Write File node — directory restrictions could be bypassed via symbolic links, allowing access to paths that should have been off-limits. Affects versions before 1.106.0. Fixed in 1.106.0.
The exposure wasn't theoretical either. According to Shadowserver Foundation scan data, more than 24,700 unpatched n8n instances were found internet-facing in early February 2026 — over 7,800 of them in Europe. Both self-hosted and n8n Cloud deployments were affected by the authenticated RCE class; the unauthenticated chains (Ni8mare, CVE-2026-25049) specifically required a publicly reachable webhook or form endpoint, which is n8n's normal, intended way of receiving external triggers — not a misconfiguration. CVE-2025-68613's KEV listing and 99.9% EPSS score make it, on its own, the single most urgent entry in this list — authenticated exploitation is a materially lower bar than it sounds, since a compromised low-privilege account or a malicious shared workflow template both qualify.
To be fully patched against the full disclosed set as of mid-2026 requires running n8n 2.14.1+ or 1.123.27+. Anything older carries exposure to at least one of the critical chains above.
The single environment variable that decides whether a disaster is recoverable
N8N_ENCRYPTION_KEY is the AES-256 key n8n uses to encrypt every stored credential — API keys, OAuth tokens, database passwords — before writing them to the database. This is documented, consistently, across every serious self-hosting guide, for one reason: getting it wrong has no fix.
If the key isn't explicitly set, n8n auto-generates one on first startup and stores it locally. Redeploy the container without preserving that exact value — a fresh container, a migrated server, a restored backup pointed at the wrong key — and every stored credential fails to decrypt permanently. Not degraded, not recoverable: every API key, OAuth token, and password has to be manually re-entered from scratch, one credential at a time, across every workflow that used them.
SQLite is the default, and it's not a production database
Out of the box, n8n stores workflows, credentials, and execution data in a local SQLite file. That's fine for evaluation, and actively wrong for anything running real business processes:
- File locking under concurrency. SQLite locks the entire database on writes; concurrent workflow executions start timing out as load increases.
- No safe live backups. Backing up SQLite while n8n is running risks corruption — there's no equivalent to PostgreSQL's
pg_dumpconsistent snapshot. - Queue mode requires PostgreSQL. Scaling execution across worker processes — the standard approach for any real production load — isn't available on SQLite at all.
- MySQL/MariaDB support is deprecated as of n8n 2.0. PostgreSQL is now the only supported production database, narrowing the migration path further for anyone who started elsewhere.
Migrating an existing SQLite instance to PostgreSQL later is possible but genuinely painful: export every workflow, credential, and execution record, then re-import against the new database — all while preserving the exact original N8N_ENCRYPTION_KEY, since credentials are encrypted with it regardless of which database stores them.
Webhooks need HTTPS and their own reverse-proxy configuration before they work correctly
Running n8n behind nginx or Traefik — the normal setup for any internet-facing instance — isn't optional configuration, it's a hard requirement for webhooks to resolve correctly. The WEBHOOK_URL and N8N_PROXY_HOPS environment variables have to be set correctly together, or incoming webhook calls fail to route to the right workflow. Getting this wrong doesn't throw an obvious error at setup time — it surfaces later as webhooks that silently never fire.
What correct, ongoing patching actually involves
Beyond initial setup, staying ahead of disclosures like the ones above is more involved than docker pull:
- Version-checking is a manual, recurring task. Confirming your running version against the latest disclosed CVE range means checking
docker exec n8n n8n --versionor the image tag indocker-compose.ymlagainst each new advisory as it's published — there's no automatic notification built in. - Webhook exposure is the deciding factor for the worst CVE class. The unauthenticated RCE chains only apply if the instance is reachable from the internet at all — which is the entire point of using webhooks as workflow triggers, so "just don't expose it" isn't a real option for most legitimate use cases.
- Recreate, not restart. As with most containerized platforms, pulling a new image and running
docker restartdoes not apply it — the container has to be recreated (docker compose up -dafter a pull), or the previous image keeps running under the same tag. - Basic-auth on the editor UI isn't enabled by default.
N8N_BASIC_AUTH_ACTIVEand its accompanying credentials need to be set explicitly — an unauthenticated editor UI reachable on the network is a separate exposure from the webhook-specific CVEs above.
Side by side
| Category | Self-Hosted | n8n for Business (Managed) |
|---|---|---|
| Security patching | Your responsibility, on an ongoing basis, against a real 2026 history of CVSS-10.0 disclosures | Handled as part of a scheduled, tested upgrade process |
| Credential encryption key | Losing it means every stored credential is permanently unrecoverable — no official fix | Managed and backed up as part of the platform, not left to you to track |
| Database | Defaults to SQLite — wrong for production; migrating to PostgreSQL later is a real, error-prone project | Production-grade PostgreSQL from day one |
| Webhook exposure | Directly in the path of the worst 2026 CVE class; must be internet-reachable to function as intended | Configured and monitored behind the same hardened perimeter as every other service |
| Reverse proxy / webhook routing | Manual WEBHOOK_URL / N8N_PROXY_HOPS configuration; failures are silent, not loud | Included, no setup required |
| Editor UI authentication | Not enabled by default; a separate setting you must remember to turn on | Enforced by default, with multi-factor authentication |
| Network isolation & firewall | Your responsibility to design and maintain | Configured and maintained, with intrusion prevention and dual-layer DDoS protection |
| Backups | Your responsibility to design, schedule, and verify — including keeping the encryption key in sync with every restore point | Daily, automated, to dedicated backup storage |
| EU data residency | Depends entirely on where you host it | Included by default |
| Setup time | Hours to days of technical work, plus ongoing maintenance time | Minutes, no ongoing technical maintenance required from you |
When self-hosting is the right call
If your team already tracks CVE disclosures, runs PostgreSQL in production, and manages reverse-proxy configuration for other services, self-hosting n8n is a legitimate, reasonable extension of existing practice — not new overhead. The calculation is different for a business without that capability already in place: everything above becomes new, ongoing work rather than something already absorbed into how the team operates.
See the platform
Same open-source platform, nothing proprietary or locked in — with the operational and security work already handled.
Explore n8n for Business