n8n CVE October 2026: upgrade without breaking FFmpeg

Two n8n advisories landed on October 5, 2026, and one of them turns any expression field on a shared instance into remote code execution. If your instance is self-hosted, the patch is a version bump. If it's self-hosted with a custom image because you shell out to FFmpeg, the patch is a version bump plus a rebuild of the one layer nobody documented.
Quick answer: The n8n CVE October 2026 batch (published October 5) is CVE-2026-86076, an expression sandbox escape rated CVSS 8.7, and CVE-2026-86995, a Git node path-restriction bypass rated 5.3; both are fixed in n8n 1.123.76, 2.37.7, and 2.38.2. If you can't upgrade tonight, setNODES_EXCLUDEto a JSON array string includingn8n-nodes-base.gitand restrict workflow-edit permission to trusted users, then upgrade. If the only reason that box is self-hosted is a shell-out FFmpeg step, move the transcode to a hosted FFmpeg API as one HTTP call so the video work survives this upgrade and the next one.
Which n8n version to move to
Pick the patched release on the line you're already running, not a new release line under time pressure. The GitLab advisory for CVE-2026-86076 lists the affected ranges as everything before 1.123.76, 2.0.0 through 2.37.6, and 2.38.0 through 2.38.1.
| If you're running | Upgrade to | Line |
|---|---|---|
| Anything below 1.123.76 | 1.123.76 | 1.x maintenance |
| 2.0.0 – 2.37.6 | 2.37.7 | 2.37 |
| 2.38.0 – 2.38.1 | 2.38.2 | 2.38 |
Anything after that trio contains the fix, including the same-week feature releases (2.41.6 on Oct 2, 2.42.3 and 2.41.7 on Oct 5, 2.43.0 on Oct 6). A newer tag isn't the same as patched if you've pinned a version below your line's fix.
The procedure is boring and should stay that way. Back up the .n8n volume and Postgres, read the release notes for every version between yours and the target, then docker compose pull && docker compose up -d with an exact tag pinned instead of latest or stable.
What each CVE actually lets someone do
The expression escape is the one that should move your evening. In n8n's expression compiler, the PrototypeSanitizer resolved its sanitizer through dynamically scoped this and didn't reject reserved class-member names, so a class field named __sanitize rebinds the sanitizer and reaches the Function constructor. Anyone who can author an expression runs code in the n8n process.
The impact has a second half that's easy to miss. On the backend, the expression author gets code execution on your host. In the editor, a colleague's saved expression runs as JavaScript in the browser session of whoever opens that workflow. On a shared instance with contractors, clients, or a forum template someone pasted in, "can edit a workflow" now reads as "can run code as n8n."
The Git node issue is quieter. Per the GitHub advisory GHSA-qgpw-8g46-w95v, the node's setUpstream operation writes an unvalidated branch.<name>.remote value into the repository config, and a later fetch or pull then reads any local Git repository the n8n process can read. It's a local file read rated 5.3, not an RCE, and only matters if you use the Git node.
One correction, because write-ups circulating this week have it wrong: the CVSS 9.4 argument injection on the Git node's Push operation is CVE-2026-44790, an earlier issue fixed in 1.123.43, 2.20.7, and 2.22.1 per GHSA-57g9-58c2-xjg3. If you patched that one a few weeks ago, you are not patched for October 5. Both batches also sit on top of n8n's October 1 bi-weekly bulletin, which already carried credential-check, unauthenticated OAuth persistence, stored XSS, MSSQL injection, and HMAC bypass advisories. That's three patch events inside a week.
Exposure isn't hypothetical. In an earlier n8n RCE round, Shadowserver counted 105,753 vulnerable instances, with over 100,000 visible through Shodan. Self-hosted n8n on a public hostname is a scanned population.
The interim mitigation if you can't upgrade tonight
n8n's documented stopgap for the Git node flaw is to block the node, which reduces reachability without fixing the code. Snyk's entry says adding n8n-nodes-base.git to NODES_EXCLUDE mitigates but doesn't obviate the flaw, and limiting workflow-edit permission to trusted users is the other half of the control. The expression escape has no node-level mitigation, because expressions aren't a node. Restrict who can edit workflows, and patch.
The variable has three gotchas, documented on n8n's block specific nodes page: it takes a JSON array string, it's read at startup only, and a bare comma-separated list is silently ignored, so a typo looks identical to a working config.
NODES_EXCLUDE='["n8n-nodes-base.executeCommand","n8n-nodes-base.localFileTrigger","n8n-nodes-base.git"]'
Those first two entries are n8n's defaults. Setting the variable replaces the default list, so leaving them out quietly re-enables the Execute Command node you thought was blocked. "[]" re-enables everything.
Notice what that env var blocks: executeCommand and readWriteFile-adjacent nodes are exactly what a hand-rolled FFmpeg step depends on. The hardened config and the DIY video pipeline are the same two nodes pulling in opposite directions.
Why this upgrade is riskier for video workflows
For most operators, docker compose pull is a no-op risk. For anyone running a custom image because a workflow shells out to FFmpeg, every patch cycle rebuilds a layer that drifts. n8n's official image went distroless in 2026, so there's no apk or apt inside it and the RUN apk add --no-cache ffmpeg line from every older tutorial doesn't build anymore. The surviving pattern copies a static FFmpeg build (or /sbin/apk and libapk.so* from Alpine) into the distroless base, and it has to be re-verified against each n8n release, because a musl mismatch surfaces as a binary that won't exec. We wrote up that decay in how to use FFmpeg in n8n without touching your Docker image.
Then there's the part no upgrade guide says out loud: upgrading n8n does nothing for the FFmpeg binary inside your image. That binary is its own patch surface with its own advisory stream, and a static build you pinned eighteen months ago is eighteen months stale. We covered that pattern in FFmpeg CVE-2026-96611: is your self-hosted build patched?.
The 3.0 breaking-changes list, scheduled for this month, finishes the job. Self-hosted n8n will require Docker (npm and npx installs are discontinued), ~/.n8n/binaryData becomes ~/.n8n/storage, the Read/Write Binary File node operations are removed, the task runner timeout drops from 5 minutes to 1 minute, the decompression cap falls from 2 GiB to 256 MiB, and unverified community packages are disabled by default. Execute Command plus Read/Write Binary File is exactly how self-hosters shuttle a file to disk, run FFmpeg, and read the output back. A 1-minute runner timeout is shorter than most real transcodes.
The same transcode step as an HTTP call
Say the workflow scales a 1080p master and burns in captions. The FFmpeg command you run today sits next to the request that replaces it:
# What your Execute Command node runs today
ffmpeg -i /data/in.mp4 -vf "scale=-2:1080,subtitles=/data/subs.srt" \
-c:v libx264 -crf 23 -c:a aac /data/out.mp4
# The same job as one API call, from an n8n HTTP Request node
curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
-H "Authorization: Bearer $FFMPEG_MICRO_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": [{ "url": "gs://your-bucket/1234567890-in.mp4" }],
"outputFormat": "mp4",
"preset": { "quality": "medium", "resolution": "1080p" }
}'
The response comes back with an id and status: "pending". Poll GET /v1/transcodes/{id} until it reads completed, then call /v1/transcodes/{id}/download for a signed URL. In n8n that's four HTTP Request nodes and a Wait node, no binary, no disk, no Execute Command. Pass URLs instead of routing bytes through n8n, which also fixes the memory blowups described in large video transcription in n8n fails: send a URL, not the file.
Two things change in your threat model when the encode moves out. Execute Command can stay disabled, which is n8n's default since v2.0 and the configuration you'd choose anyway after this week. And the FFmpeg binary stops being yours to patch. FFmpeg Micro runs the managed toolkit behind one REST endpoint, and more than 300 builders already drive it from Make or n8n. The free tier is 200 tokens at sign-up with no card, roughly 33 minutes of video, billed per second of input with no rounding up to the minute and no charge for failed jobs.
When self-hosting still earns its keep
Offloading the encode doesn't mean you should move to n8n Cloud. Self-hosting still wins when workflows reach databases or services on a private network, when data residency rules say the orchestration can't leave your VPC, or when your volume makes Cloud pricing worse than a VM. What changes is the reason for the custom image. Run the stock n8n image, keep Execute Command blocked, and your patch cycle becomes a tag bump instead of a rebuild.
A hosted encode is also the wrong call in two cases: files above your plan's input cap (100 MB on Free, 1,024 MB on Starter, 2,048 MB on Pro), and jobs where the media legally cannot leave your infrastructure. If that's you, budget for owning a maintained FFmpeg build and a runner image, and put both in the same patch calendar as n8n.
Common pitfalls during this upgrade
Most of the pain in an unplanned security jump comes from four avoidable places.
NODES_EXCLUDEset as a comma-separated list. It's silently ignored with no warning in the UI. It must be a JSON array string, read at startup, so the container has to restart.- Overwriting the defaults. Setting the variable to just
["n8n-nodes-base.git"]re-enablesexecuteCommandandlocalFileTrigger. Include them explicitly. - Rebuilding the custom image without re-pinning FFmpeg. A fresh
lateststatic build against a new n8n base is where the musl mismatch bites, and the error is a node that fails instantly with no usable message. - Skipping the backup. Snapshot the
.n8nvolume and Postgres before the jump. Security patches get applied in a hurry, and that's when you find out your volume wasn't where you thought.
FAQ
Is the October 2026 n8n CVE the same as the CVSS 9.4 Git node bug?
No, the October 5 batch is different. CVE-2026-44790, the CVSS 9.4 argument injection on the Git node's Push operation, was fixed earlier in 1.123.43, 2.20.7, and 2.22.1. The Git node CVE in the October 5 trio is CVE-2026-86995, a CVSS 5.3 local repository read.
Will upgrading n8n break my FFmpeg video step?
Upgrading n8n breaks a baked-in FFmpeg step whenever the base image changes underneath your custom layer, which the distroless switch already did once in 2026. The upgrade also leaves your FFmpeg binary at whatever version you pinned, so it inherits none of FFmpeg's own security fixes. An HTTP call to a hosted FFmpeg API has no image layer to break, which is why we recommended it when n8n disabled the Execute Command node.
If I stop shelling out to FFmpeg, do I still need to self-host n8n?
Many builders don't need their own instance once the encode is an HTTP request. Private-network access, data residency, and volume economics are real reasons to keep one, but a shell-out media step isn't one of them. If video processing was the only blocker, n8n Cloud plus a hosted FFmpeg API removes the patch cycle entirely.
How long does switching the video step to an API take?
Replacing one Execute Command node with HTTP Request nodes is usually under an hour: request a presigned upload URL, PUT the file, confirm, create the transcode job, poll, download. The free tier covers the testing, and failed jobs aren't billed, so a broken first attempt costs nothing.
You can run that sequence before the upgrade. The quickstart creates a temporary API key and walks the presigned upload, transcode, poll, and download steps, with the request and response shown at each stage, so you'll know whether your video step survives this patch cycle before the maintenance window.
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

n8n 3.0 breaking changes kill your FFmpeg step: what to change
n8n 3.0 breaking changes that kill a self-hosted FFmpeg workflow: removed binary file nodes, a 60-second runner timeout, a 256 MiB cap, and what to change.

n8n 3.0 breaking changes kill your FFmpeg step. Send it HTTP.
n8n 3.0 breaking changes kill the npx + host ffmpeg video step. Here's the Docker Compose and distroless Dockerfile that work, and the HTTP alternative.

Why n8n says "No usable ffmpeg was found" and what to do about it
"No usable ffmpeg was found" in n8n means the server has no FFmpeg binary, and n8n's installer makes it impossible for a community node to ship one. Three real fixes.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free