n8nsecurityffmpeg

n8n CVE October 2026: upgrade without breaking FFmpeg

··10 min read
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, set NODES_EXCLUDE to a JSON array string including n8n-nodes-base.git and 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 runningUpgrade toLine
Anything below 1.123.761.123.761.x maintenance
2.0.0 – 2.37.62.37.72.37
2.38.0 – 2.38.12.38.22.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.

  1. NODES_EXCLUDE set 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.
  2. Overwriting the defaults. Setting the variable to just ["n8n-nodes-base.git"] re-enables executeCommand and localFileTrigger. Include them explicitly.
  3. Rebuilding the custom image without re-pinning FFmpeg. A fresh latest static 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.
  4. Skipping the backup. Snapshot the .n8n volume 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.

Software EngineeringVideo ProcessingFFmpegCloud ArchitectureAPI DesignAutomation

Ready to process videos at scale?

Start using FFmpeg Micro's simple API today. No infrastructure required.

Get Started Free