A remote URL isn't safe: the FFmpeg protocol whitelist bypass

Most pipelines hand FFmpeg a URL because it works. A webhook link, a Drive share, an RTSP camera, a generation API: you drop it after -i and FFmpeg happily opens it. After the batch of CVEs published on October 8, 2026, that one convenience is where almost all of the new risk lives, and for three of the bugs there's no version to upgrade to.
Quick answer: Passing a remote URL straight to FFmpeg is not safe as of October 2026. The ffmpeg protocol whitelist bypass in CVE-2026-107697 lets a crafted HLS master playlist makeparse_playlist()open child playlists over protocols you excluded, and the RTSP, SFTP and MOVpsshissues from the same batch affect FFmpeg through 9.0.2 with no fixed release reported. If you keep your own binary: fetch the file with a real HTTP client, validate the final URL after redirects, give ffmpeg a local path only, keep passwords out ofsftp://URLs, and cap memory and CPU with rlimits. If the video step runs behind a media API such as FFmpeg Micro, you submit a file and poll for the output, so no ffmpeg process in your deployment ever resolves a redirect.
Which October 2026 FFmpeg CVEs have a fix and which don't
The useful split in this batch isn't severity, it's whether a release exists you can install. FFmpeg 9.0.2 "Lei" shipped September 18, 2026 and 8.1.3 "Hoare" followed on September 21. Per ffmpeg.org/download 9.0.2 is still the newest stable build, so there's no 9.0.3 waiting for you.
| CVE | Where it lives | Status per trackers |
|---|---|---|
| CVE-2026-107697 (4.3) | HLS demuxer `parse_playlist()`, child playlists over disallowed protocols and non-media local files | Fixed in 8.1.3 |
| CVE-2026-107695 (6.5) | HLS demuxer, master-playlist tags accepted inside a media playlist, `hls_read_header()` loops | Fixed in 8.1.3 |
| CVE-2026-107660 (4.8) | `tls_open()` in `tls_mbedtls.c`, hostname check skipped for IP-literal hosts | Fixed in 8.1.3 and 9.0.2 |
| CVE-2026-107698 (5.4) | RTSP `ff_rtsp_connect()`, 3xx `Location` not validated, SSRF | Listed fixed in 7.1.4 and 8.0.2 |
| CVE-2026-107696 (6.5) | RTSP `ff_rtsp_connect()`, no redirect limit, self-302 saturates a core | Through 9.0.2, no fix reported |
| CVE-2026-107675 (5.9) | libssh SFTP handler, no host-key verification | Through 9.0.2, no fix reported |
| CVE-2026-107678 (4.7) | MOV `mov_read_pssh()` into `av_encryption_init_info_free()`, stack exhaustion | Through 9.0.2, no fix reported |
| CVE-2026-107676 | `av_dynamic_hdr_plus_to_t35()` writes up to 3 uninitialized bytes into output | Fixed version is 9.1, unreleased |
One discrepancy matters. The hol.org entry for CVE-2026-107698 puts the RTSP SSRF as fixed in 7.1.4 and 8.0.2, while VulDB's entry for its sibling CVE-2026-107696 lists the same function as affected through 9.0.2 with no fix. Both can be true: one commit added Location validation, and nothing added a redirect counter. Treat RTSP redirect handling as unfixed on every current release, whatever a green scanner row on 107698 says.
The branch problem bites the people who are most current. The HLS fixes landed on the 8.1 line, so a Dockerfile pinned to a 9.x tag has no patched release for CVE-2026-107697 or CVE-2026-107695 without moving back a branch. The CVE-2026-96611 MOV/HEIF overflow from September had the same shape, except there "upgrade" was an answer. This week, for half the list, it isn't.
Is -protocol_whitelist still a boundary?
-protocol_whitelist is a hardening layer, not a security boundary, and CVE-2026-107697 is the demonstration. The flag is enforced when FFmpeg opens the URL you passed, but the HLS demuxer then opens whatever the playlist points at, and the bypass in parse_playlist() means a crafted master playlist can reach child playlists over protocols you excluded or local files that aren't media. allowed_extensions is bypassed by the same bug, so adding it buys you nothing here.
Keep setting the flag anyway. It still blocks the direct-injection class, a proven primitive: elttam's writeup Your House Has an FFmpeg Problem showed Home Assistant passing an attacker-controlled media_id to -i, where concat:, file: and subfile: were enough to read /proc/self/environ and lift the SUPERVISOR_TOKEN. The patch in Home Assistant 2026.6.2 was -protocol_whitelist http,https,file,tcp,tls, and that fix is still correct. It just isn't the whole fence.
How to harden when you must keep your own binary
The approach that survives this batch: stop letting ffmpeg do network I/O at all. Assume you still run a local binary in n8n, a worker, a Lambda or a container.
- Fetch the file with a real HTTP client. Use
curl,requests,fetchor an HTTP Request node, with redirects capped and a size limit. That client is code you can patch on your own schedule. - Validate the final URL, not the one you were given. Follow redirects manually, then check the last hop's scheme and resolved IP before you download the body.
- Hand ffmpeg a local path and nothing else. No
http://, nortsp://, nosftp://, noconcat:. A redirect ffmpeg never sees can't loop it or point it at169.254.169.254. - Never put a password in an
sftp://URL. CVE-2026-107675 is missing host-key verification in the libssh handler, so a machine-in-the-middle can capture that password, serve forged media back, or receive the output you upload. Credentials in a URL also land in your process list and your logs. Use a real SFTP client with a known_hosts check and key auth, then pass the downloaded path. - Cap memory, CPU and output size. CVE-2026-107678 crashes the process on an MP4 carrying tens of thousands of tiny
psshboxes, with quadratic CPU on the way down, and CVE-2026-107695 hangshls_read_header()forever. Containment bounds both.
The wrapper shape, with numbers worth starting from:
#!/bin/bash
set -euo pipefail
# fetch with your own client, cap redirects and size
curl -sS --max-redirs 2 --max-filesize 104857600 \
--proto '=https' -o /tmp/in.mp4 "$VALIDATED_URL"
# magic-byte sanity check before ffmpeg parses anything
file --mime-type -b /tmp/in.mp4 | grep -qE '^video/' || exit 65
( ulimit -v 1048576 # ~1 GiB address space
ulimit -t 120 # 120 CPU-seconds
ulimit -f 2097152 # ~2 GiB max output
timeout 300 ffmpeg -nostdin -y \
-protocol_whitelist file \
-t 600 -i /tmp/in.mp4 \
-c:v libx264 -preset veryfast /tmp/out.mp4 )
URL validation has to look at the end of the chain:
import dns from 'node:dns/promises';
import net from 'node:net';
const PRIVATE = ['10.','127.','169.254.','192.168.','172.16.','172.17.'];
export async function resolveSafe(url, hops = 2) {
let current = url;
for (let i = 0; i <= hops; i++) {
const u = new URL(current);
if (u.protocol !== 'https:') throw new Error('scheme not allowed');
const { address } = await dns.lookup(u.hostname);
if (!net.isIPv4(address) || PRIVATE.some(p => address.startsWith(p)))
throw new Error(`blocked host ${u.hostname} -> ${address}`);
const res = await fetch(current, { redirect: 'manual', method: 'HEAD' });
if (res.status < 300 || res.status > 399) return current;
current = new URL(res.headers.get('location'), current).toString();
}
throw new Error('too many redirects');
}
A malformed or unreachable input fails here with blocked host metadata.internal -> 169.254.169.254 before ffmpeg starts. Let the binary handle it and the best case is Invalid data found when processing input, the worst a silent request to something on your private network.
The two bugs no protocol flag touches
Two bugs in this batch fire on an ordinary uploaded file, so every protocol control above is irrelevant to them. CVE-2026-107678 is the MOV pssh stack exhaustion, reachable from any MP4 a user hands you, with no upstream fix on Ubuntu's security page. CVE-2026-107676 is quieter and arguably worse: when tone_mapping_flag is 0, av_dynamic_hdr_plus_to_t35() leaves up to three payload bytes uninitialized, so a remux of crafted Matroska T.35 or HEVC/AV1 SEI metadata writes leaked process memory into a file you then publish. Its listed fixed version is 9.1, which doesn't exist yet.
For those two, the levers are containment and input policy: rlimits, a short wall-clock timeout, a container with no credentials in its environment, and strict HDR metadata handling if you remux files you didn't create.
The structural version: no binary, no redirect
If the video step runs behind an API, the vulnerable binary isn't in your deployment, so there's nothing to patch this week. That's separate from how a vendor runs its own stack, which nobody should take on faith.
FFmpeg Micro's documented flow is a presigned upload to Google Cloud Storage, a POST /v1/transcodes whose inputs[].url is the resulting gs:// path, a poll on the job id, and a signed download URL at the end:
curl -s -X POST https://api.ffmpeg-micro.com/v1/transcodes \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"inputs":[{"url":"gs://your-bucket/1760000000-video.mp4"}],
"outputFormat":"mp4",
"preset":{"quality":"medium","resolution":"1080p"}}'
Nothing in that request is an http://, rtsp:// or sftp:// URL. You uploaded the bytes yourself over a presigned PUT, the same "fetch it first, pass a path" discipline as the list above. No ffmpeg process in the chain resolves a redirect you didn't inspect. You can start on the free tier with 200 tokens, roughly 33 minutes of video, and no card.
That removal is why this keeps coming up for n8n and Make builders. If your workflow shells out to ffmpeg from Execute Command, you own this patch cycle on top of n8n's own, which the October n8n CVE post covers. If it's an HTTP Request node instead, you never touch your Docker image and your FFmpeg version stops being your responsibility.
Common pitfalls
Most of the hardening pasted into pipelines this week will be subtly inert. The failures that show up in real code:
- Putting
-protocol_whitelistafter-i, where FFmpeg ignores it. It has to come before the input. - Trusting
allowed_extensionsas a second layer against CVE-2026-107697. Both it and the whitelist are bypassed by the same bug. - Validating the submitted URL, then handing ffmpeg that same URL. The check belongs on the final hop, and ffmpeg should open a local file.
- Capping CPU with
ulimit -tand calling it a timeout. A process hanging on a socket uses no CPU seconds, and a separate wall-clocktimeoutis what stops it.
FAQ
Is -protocol_whitelist still worth setting after CVE-2026-107697?
-protocol_whitelist is still worth setting, because it blocks the direct-injection class where an attacker-controlled string reaches -i and uses concat:, file: or subfile:. CVE-2026-107697 changes its status, not its value: the flag runs when FFmpeg opens your URL, and it doesn't govern what a demuxer opens afterward.
Does upgrading to FFmpeg 9.0.2 fix the October 2026 CVEs?
Upgrading to FFmpeg 9.0.2 does not clear this batch. 9.0.2 shipped September 18, 2026, before the October 8 disclosure, and the RTSP self-redirect loop (CVE-2026-107696), the SFTP host-key issue (CVE-2026-107675) and the MOV pssh crash (CVE-2026-107678) all affect FFmpeg through 9.0.2 with no fixed release. The two HLS bugs are fixed in 8.1.3 only, so a 9.x pin has no patched release to move to.
Am I exposed if I only pass my own HTTPS URLs to ffmpeg?
You can still be exposed when the URLs are your own, because exposure depends on the final hop, not the first one. A CDN or storage link that 302s to a third party, a signed URL whose path segment comes from user input, or an HLS manifest you host but didn't author all put attacker-influenced content in front of parse_playlist().
Does CVE-2026-107660 affect my build if I linked OpenSSL or GnuTLS?
CVE-2026-107660 affects only builds linked against mbedTLS, since the missing hostname check for IP-literal hosts is in libavformat/tls_mbedtls.c. Run ffmpeg -version and check the configuration: line for --enable-mbedtls. It's already fixed in both 8.1.3 and 9.0.2.
If you'd rather the answer to "which FFmpeg CVEs apply to us" be "we don't ship an FFmpeg binary," the quickstart runs the whole upload, transcode, poll and download flow with a temporary key, free and without a card. See the job shape before you decide whether to keep patching your own.
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 CVE October 2026: upgrade without breaking FFmpeg
n8n CVE October 2026: patch to 1.123.76, 2.37.7, or 2.38.2, what each flaw allows, NODES_EXCLUDE mitigations, and how to upgrade without breaking FFmpeg.

FFmpeg CVE-2026-96611: is your self-hosted build patched?
FFmpeg CVE-2026-96611 affects every build before 9.0. How to check the version your pipeline actually runs, who's exposed, and how to patch a container.

Run an ONNX Upscaler in FFmpeg 9's DNN Filter Graph
FFmpeg onnx dnn filter in 9.0: the real dnn_processing chain, NCHW float32 model limits, silent CUDA-to-CPU fallback, and what hosting it actually costs.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free