Sixteen security advisories landed on the n8n repository today. Twelve are rated high, four medium, and the fixes are in 2.40.1, 2.39.6 and 1.123.80. If you self-host and you are still on the version you deployed in July, you are now behind on all three release lines at once.
That is not an unusual day any more. June closed with 11 high-severity advisories. July with 18. August with 16. September has produced 17 with two weeks still to run. Across the whole repository there are 196 published advisories, 22 of them critical — and every one of those 22 was published between December 2025 and May 2026.
We run n8n in production. It is the orchestration layer for our own content and outbound pipelines, and it holds credentials for around a dozen services we would rather not hand to anybody. So we read this feed the way you read the changelog of something you own rather than something you are evaluating. What changed in our heads over the last nine months was not the patch cadence. It was where the risk actually sits.
Almost every self-hosted n8n we have been asked to look at is defended in exactly one place: the webhook. TLS in front, maybe a shared secret in a header, maybe an IP allowlist. The webhook is genuinely the part an attacker reaches first, and it is not where they get anything. The overwhelming majority of n8n's 2026 advisories require an authenticated workflow editor — and an authenticated workflow editor is, by design, a shell on the host plus every credential the instance has ever stored. The webhook is the doorbell. The editor is the building.
196
published security advisories on the n8n repository
22
of them rated critical, all between Dec 2025 and May 2026
321
live instances that still accepted a token leaked to public GitHub
24,700+
instances still unpatched against a CVE on the CISA KEV list
What actually got hacked
Four incidents, and they fail in four different ways. That variety is the useful part — if you only defend against the shape of the last one, you are defending against a quarter of the problem.
Ni8mare: CVSS 10.0, no login required
Cyera Research Labs published Ni8mare on 7 January 2026 — CVE-2026-21858, CVSS 10.0, unauthenticated. They reported it on 9 November 2025 and n8n shipped the fix nine days later in 1.121.0, which is a good disclosure story. The uncomfortable part is what Shadowserver counted at disclosure: more than 105,000 vulnerable instances out of more than 230,000 n8n servers visible on the internet.
The chain is worth reading in full even if you patched it in November, because it shows how a self-hosted automation tool turns one small parsing decision into root.
Ni8mare — CVE-2026-21858, from an anonymous HTTP request to a shell
Step one is the whole bug. A Form trigger expects multipart/form-data. Send the same request as application/json and the regular body parser runs instead, which hands the attacker control of req.body.files — including the filepath field. Step two: the Form node's prepareFormReturnItem() iterates those entries and calls copyBinaryFile() on each. It reads whatever path it was given. That is an arbitrary local file read, from an unauthenticated HTTP request, on a default install.
Everything after that is filesystem knowledge rather than vulnerability research. The n8n SQLite database holds the user id, email and password hash. The config file beside it holds the encryption secret. With both, you forge the _n8n-auth_ session cookie for the instance owner, and once you have an admin session you do not need a second bug: create a workflow with an Execute Command node and run whatever you like. The lesson we took was not "patch faster". It was that on a system which stores its signing material on the filesystem beside its data, an arbitrary file read and a session forgery are the same bug.
CVE-2025-68613: the one CISA had to put on the KEV list
The bug that was actually exploited in the wild is older and much quieter. CVE-2025-68613, CVSS 9.9, expression injection leading to remote code execution, fixed in 1.120.4, 1.121.1 and 1.122.0 back in December 2025. It needs an authenticated user — which is precisely why it sat in so many backlogs.
CISA added it to the Known Exploited Vulnerabilities catalogue on 11 March 2026 on evidence of active exploitation, and gave US federal agencies until 25 March to patch. Shadowserver was still counting more than 24,700 unpatched instances exposed online in early February 2026 — 12,300 in North America, 7,800 in Europe. Two months after a fix existed, on a bug somebody was demonstrably using.
“"Requires an authenticated user" does a lot of work in a risk assessment and almost none in reality. On an n8n instance, authenticated users are everyone you gave editor access to, plus anyone who finds one bug in the auth path.”
No bug required: 4,576 API tokens in public commits
On 5 August 2026 GitGuardian published what it found by searching public GitHub commits for n8n API tokens: 4,576 unique tokens pointing at 1,255 distinct hostnames. 896 of those instances were reachable. 321 still accepted the leaked token — 36% of everything reachable. They also found 372 n8n MCP tokens, seven of which were still valid.
Two leak paths did most of the damage, and the second should make anyone using coding agents uncomfortable. The first is ordinary: a .env file committed with N8N_URL and N8N_API_KEY side by side, so the token arrives complete with its own address. The second is agent configuration — .claude/settings.json files containing curl commands with the key and the hostname baked in. That file does not feel like a secret store, which is exactly why it ends up in a commit.
Age compounds it. n8n 1.78.0, in February 2025, introduced a 30-day default expiry on API keys. Keys issued before that have no exp claim at all — they are valid forever. A token leaked two years ago is a live credential today, which is most of the explanation for that 36%.
What a valid token buys is worth spelling out, because many teams treat the public API as read-only convenience. GitGuardian demonstrated four abuses: enumerate users, workflows and instance configuration; create workflows that use credentials already stored on the instance; exfiltrate whole data tables through execution results; and add an HTTP Request node that posts raw credentials to a server the attacker controls. Nothing gets decrypted by the attacker at any point. You simply ask n8n to use the credential and tell it where to send the result. Their disclosure went to three hosting providers covering around 100 instances and four organisations directly; six organisations never replied.

The Metabase incident: the tool next to the tool
The fourth is n8n's own, and it is the least technical and the most relevant to how most teams are structured. On 3 August 2026 an attacker gained unauthorised access through a vulnerability in Metabase — a third-party analytics tool n8n used internally. n8n discovered it on the 6th and disclosed on the 8th. 136 records containing names and email addresses of both self-hosted and Cloud users were accessed; five of those held bcrypt hashes of Cloud passwords, and a historical bug may have exposed 25 Cloud passwords in plaintext. Affected users were told to reset.
Nobody attacked n8n. They attacked the dashboard sitting next to it. If your automation host, your BI tool, your log viewer and your queue dashboard all share a network and the same unexamined "internal, it's fine" status, then hardening n8n hardens one door out of four.
| Advisory | What it does | Who can trigger it | Fixed in |
|---|---|---|---|
| CVE-2026-21858 (Ni8mare) | Content-type confusion in the Form trigger → arbitrary file read → forged admin session → RCE | Anyone who can reach a Form trigger | 1.121.0 |
| CVE-2025-68613 | Expression injection → remote code execution. On the CISA KEV list since 11 Mar 2026 | Any authenticated user | 1.120.4 / 1.121.1 / 1.122.0 |
| GHSA-9rhv-fhr8-7q5r | Inline Agent node-tool introspection decrypts any credential on the instance, with no ownership check | Authenticated editor | 2.40.1 / 2.39.6 / 1.123.80 |
| GHSA-597w-c3jh-g8fg | Path traversal in signed resume URL generation enables cross-project approval forgery | Authenticated editor | 2.40.1 / 2.39.6 / 1.123.80 |
| GHSA-w24g-6454-7w7f | NoSQL injection in the MongoDB Chat Memory node discloses cross-session chat history | Unauthenticated | 2.40.1 / 2.39.6 / 1.123.80 |
| GHSA-fmmv-p585-7c8x | Community package install validation bypass via PubSub in queue-mode deployments | Anything that can publish on the internal PubSub channel | 2.40.1 / 2.39.6 / 1.123.80 |
| GHSA-9x83-43r8-5hwc | $fromAI prototype leak leading to code execution on the host | Authenticated editor | 1.123.73 / 2.35.4 / 2.36.2 |
| GHSA-mwp5-2m32-r54h | Git node RCE via repository-local config | Authenticated editor | 1.123.73 / 2.35.4 / 2.36.2 |
| GHSA-4r56-g65c-fm83 | Shared-workflow editor exfiltrates credentials through an inline sub-workflow | Anyone a workflow is shared with | 1.123.73 / 2.35.4 / 2.36.2 |
| CVE-2026-86084 | Disabled OIDC SSO endpoints stay active and keep issuing valid sessions | Anyone with an identity in an IdP you thought was switched off | 2.38.2 / 2.37.7 / 1.123.76 |
| CVE-2026-86077 | Anonymous approval-gate bypass via a reused resumeToken over the chat WebSocket | Unauthenticated | 2.38.2 / 2.37.7 / 1.123.76 |
The threat model people get wrong
Read that table as a list and the pattern falls out immediately. Most 2026 n8n bugs do not need an anonymous visitor. They need somebody who can edit a workflow.
- An editor can read credentials they do not own— GHSA-9rhv-fhr8-7q5r, in today’s batch, lets inline agent node-tool introspection decrypt any credential on the instance with no ownership check. Project boundaries were the control. They were not a boundary.
- Being shared with is enough — GHSA-4r56-g65c-fm83 from the August batch lets an editor a workflow was shared with exfiltrate credentials via an inline sub-workflow. The person you gave read-ish access to had write-everything access.
- Expressions reach the host — the
$fromAIprototype leak (GHSA-9x83-43r8-5hwc) ends in code execution on the host, and the Git node (GHSA-mwp5-2m32-r54h) gets there through a repository-local config file. Neither looks like an exploit while you are reading the workflow. - Off is not always off — CVE-2026-86084 found that disabled OIDC SSO endpoints stayed active and kept issuing valid sessions. If you turned SSO off in the UI rather than removing it, you had a login path you believed was closed.
The reason this class keeps producing bugs is structural, not sloppy. n8n's editor is not an admin panel, it is a programming environment. A Code node is arbitrary JavaScript in the host process. An expression is arbitrary JavaScript in the host process with friendlier syntax. The credential store exists so workflows can use credentials without a human ever seeing them — which means the process holding the decryption key is the same process running code your users write. Every ownership check and project boundary is a software check inside a runtime whose job is to execute untrusted expressions. Getting that right 196 times in a row is not a realistic expectation of anyone.
So the honest statement of the threat model is this: anyone with editor access to your n8n has a shell on that host and every credential on that instance. Not "could escalate to" — has. Treat an n8n editor account exactly the way you treat SSH access to the box, because that is what it is. Once you do, the advisory feed stops reading like a stream of surprises and starts reading like a stream of confirmations, and you can make architectural decisions instead of reactive ones.

There is a corollary most teams miss, and it stings a little because it punishes the people who did the responsible thing. The approval gates you bolt on top are part of this surface too. We run human approvals through signed resume URLs on the /webhook-waiting/ path, precisely because that lets a person approve from a phone without holding an n8n account at all. Today's batch includes GHSA-597w-c3jh-g8fg, a path traversal in signed resume URL generation enabling cross-project approval forgery, and the 2 September batch included CVE-2026-86077, an anonymous approval-gate bypass via a reused resumeToken over the chat WebSocket. Both break exactly the mechanism you reach for when you want a human in the loop. A gate is a feature, and features have CVE budgets.
How to check your instance in fifteen minutes
None of this needs a security team. Five commands, in order, and at the end you will know whether you have a Tuesday-afternoon problem or a this-evening problem. Start with the version, and read it from the running container rather than the compose file — the two disagree more often than anyone expects, usually because a tag was pinned once and a rebuild never happened.
Next, run the audit that ships in the box and that almost nobody runs. It covers five categories — credentials, database, nodes, instance and filesystem — and it takes seconds.
Then read the environment the process actually received, rather than the one you believe you set. Filter the secrets out before you print it — that list contains your encryption key, and terminal scrollback is where secrets go to survive.
We found N8N_BLOCK_ENV_ACCESS_IN_NODE missing on an instance whose hardening notes we had written ourselves. Without it, a Code node can read process.env — and process.env is where N8N_ENCRYPTION_KEY lives. Any imported template can lift the key protecting every credential on the instance in about three lines, and it looks like ordinary workflow code while it does it. That one is worth a container restart tonight rather than on Thursday.
Fourth, go hunting for your own tokens the way GitGuardian went hunting for everyone else's. Search history, not just the working tree — the whole point of those 4,576 tokens is that most of them were removed from HEAD and left in the log.
Finally, ask the internet what it can see — from outside. This is the check teams get wrong most often, because they run curl on the box itself, or from a laptop already on the VPN, and collect a comforting 200 that no external client would ever receive. Split DNS and a stale hosts file will both lie to you here, silently and cheerfully. Pin the resolution to the public address and go through the real path.
What you want back is 403, 404 or a refused connection on everything except the specific webhook paths you deliberately publish. If / returns the editor login page, your instance is on the same list as the 230,000 Shadowserver counts, and the only thing standing between you and the next unauthenticated 10.0 is the version number you checked in step one.
Hardening that survives the next advisory
Patching is table stakes and it is also not a strategy, because today's batch will have a successor in October. What we optimise for is reducing what a successful bug gets you — the changes that keep paying out on vulnerabilities nobody has published yet.
- Take the editor off the internet — VPN, tailnet, or an allowlisted reverse proxy. This is the highest-value change on the list because it neutralises the entire authenticated-editor bug class, which is most of the 2026 feed. Everything below is a supporting act.
- Split public intake from private execution — one instance that only receives webhooks and writes a queue row, one instance that does the work and holds the credentials, and no inbound path to the second one at all.
- Turn off the public API unless you use it —
N8N_PUBLIC_API_DISABLED=true. A leaked token against a disabled API is a dead string. That is 321 instances’ worth of evidence for one environment variable. - Leave Execute Command excluded — n8n v2 already excludes
n8n-nodes-base.executeCommandandn8n-nodes-base.localFileTriggerby default. If somebody re-enabled them for one workflow eighteen months ago, that trade is still running today. - Block env access in Code nodes —
N8N_BLOCK_ENV_ACCESS_IN_NODE=true, so a Code node cannot read the encryption key out of the process it is running in. - Confine file access —
N8N_RESTRICT_FILE_ACCESS_TOpins file nodes to one directory andN8N_BLOCK_FILE_ACCESS_TO_N8N_FILES=trueputs the database and config out of reach. Ni8mare read two files. This is the setting that makes that read worthless. - Rotate API keys and give them an expiry — every key issued before 1.78.0 is immortal. Revoke them all and reissue. The ones genuinely in use will announce themselves within a day.
That file is the cheap half. The other half is topology, and topology is the part that keeps working when a component you do not control turns out to have a 10.0 in it.
Public intake, private execution
This is what we run. The inbox instance receives a webhook, writes one row to a job queue and returns 200 — no AI nodes, no outbound HTTP calls, no credentials that would hurt to lose. The worker has no public URL at all; it polls the queue outbound over a private network, and the editor is reachable only from inside that network. The reverse proxy in front of the inbox returns 403 to the public for everything except the handful of webhook paths we publish deliberately.
It took about two days to build and it has the best ratio of anything on this list, because it is the only item still working when the next 10.0 lands on a component we do not control. It also has an operational cost worth being honest about: two instances to patch instead of one, and a class of debugging where the answer is "the job is sitting in the queue and the worker is asleep". We think that is a good trade. If your n8n runs internal glue only, with no public triggers at all, skip the split entirely and put the whole thing behind the VPN — same benefit, none of the cost.

One last thing that is not an environment variable. Imported community templates are code that will run with all of your credentials. The template library is large and genuinely useful and none of it is reviewed by anybody. We read every HTTP Request URL and every Code node before activating one, every time, and we have declined a few. Today's batch even includes a community package install validation bypass via PubSub in queue-mode deployments (GHSA-fmmv-p585-7c8x), so "we only install packages ourselves" is itself a control with a published bypass.
Assume credential disclosure rather than hoping otherwise — every one of these chains ends at the credential store. Rotate the secrets themselves at each provider. Rotating N8N_ENCRYPTION_KEY on its own does not help, because an attacker who used your credentials already has the plaintext, and changing that key makes every stored credential permanently unreadable to you. Then revoke every API key and reissue. Then read the execution history and the workflow list: look for workflows nobody created, HTTP Request nodes pointing at hosts you do not recognise, and executions that ran at hours when nobody was working. Check users and SSO settings too — a forged session leaves no trace, but the account somebody added afterwards does.
The fifteen-minute version
- Check the running version, not the compose file. Floors today are 2.40.1, 2.39.6 or 1.123.80.
- Run n8n audit with --days-abandoned-workflow=30. It ships in the box and takes seconds.
- Confirm N8N_BLOCK_ENV_ACCESS_IN_NODE=true — without it a Code node can read your encryption key.
- Search git history, not just HEAD, for N8N_API_KEY — including .env and agent config files.
- Test reachability from outside your own network with --resolve. Split DNS will lie to you locally.
- Disable the public API if you do not use it. 321 live instances honoured a leaked token.
- Get the editor off the internet. It is a shell plus every credential, not an admin panel.
- Read every imported template before activating it — it runs with all of your credentials.
Where to start
If you do one thing today, do the reachability check. It takes five minutes and it decides everything else: an instance the public cannot reach turns most of this advisory feed into ordinary maintenance, and an instance serving its login page to the internet turns the next disclosure into an incident. The version check is second, the audit third.
If you would rather not work through it alone:we audit and harden self-hosted n8n and automation stacks — version and advisory exposure, the checks above run properly, credential and token hygiene, and the network split where it earns its cost. It is a small, finite piece of work, and you get a written finding list whether or not you have us change anything. Get in touch if that is useful. And if you do it in-house instead, we would genuinely rather you did it this week than hired anyone.









