FFmpeg 21 zero-days: 183-byte AV1 RTP PoC
Contents
TL;DR
What’s affected Environments that process external video, audio, playlists, or RTSP URLs with FFmpeg. depthfirst lists 9 of the 21 findings as CVE-2026-39210 through CVE-2026-39218, but public NVD/CVE Services records were not available at the time checked
Entry point The AV1 over RTP depacketizer. Opening an attacker-controlled RTSP stream with ffmpeg -i rtsp://... reaches a PoC that controls flow from a 183-byte RTP packet
What to check OS packages, containers, static builds, and FFmpeg bundled inside Python, Node, and desktop apps. Do not rely only on CVE lists; compare FFmpeg’s security page with distributor backports
depthfirst published “21 Zero-Days in FFmpeg” on June 2, 2026. The important part is not only that an AI system found many vulnerabilities. The report includes DFVULN-127, a path that starts from an RTSP URL and reaches a proof of concept with control-flow impact.
According to depthfirst and secondary reporting, 9 of the 21 findings are treated as CVE-assigned, while the remaining 12 are described under depthfirst’s own IDs.
The affected areas include the TS demuxer, swscale, DASH demuxer, VP9 decoder, RTP/RTSP code, and CAF/AVI demuxers. They sit near FFmpeg’s external-input parsing paths.
Here, “zero-day” does not mean a vulnerability confirmed as exploited in the wild. It is better treated as a set of previously undisclosed vulnerabilities that moved into the disclosure, fix, and numbering process.
Public CVE records, distributor backports, and bundled-binary updates move on separate timelines.
In the earlier Claude Mythos Preview article, I covered Anthropic’s private model finding a 16-year-old H.264 vulnerability in FFmpeg.
The depthfirst report goes a step further: a commercial autonomous security agent produced 21 findings in an approximately $1,000 run, and at least one path was pushed beyond “input that crashes” into “input that controls the instruction pointer.”
The 9 CVE-labeled issues and 12 unnumbered ones
depthfirst lists CVE-2026-39210 through CVE-2026-39218 as the CVE-labeled set.
The original article still has a sentence saying “Eight”, but the listed numbers total 9, and The Hacker News also treats them as 9.
Most are heap buffer overflows, stack buffer overflows, or integer overflows.
The words look similar in a table, but the reachable code paths differ.
| ID | Path | Cause described by depthfirst |
|---|---|---|
| CVE-2026-39210 | TS demuxer | Missing length check before a 2-byte read |
| CVE-2026-39211 | swscale | Missing upper bound in size calculation from externally controlled parameters |
| CVE-2026-39212 | ffmpeg_opt.c | Recursive preset-file option parsing without a depth limit |
| CVE-2026-39213 | yuv4mpegenc rawvideo | Missing dimension validation against packet size |
| CVE-2026-39214 | SDT handling | Remaining capacity is not tracked while writing service entries. Origin dates to 2003 |
| CVE-2026-39215 | update_mb_info() | A later call writes 12 bytes past an allocated buffer |
| CVE-2026-39216 | img2enc.c | A safe chroma-size path was replaced with a size derived from dimensions |
| CVE-2026-39217 | VP9 decoder | A refactor of the size-update function missed reallocating the tile thread buffer |
| CVE-2026-39218 | DASH demuxer | Negative duration is accepted, producing a negative fragment-array index |
As of June 16, 2026, NVD API and CVE Services API did not return public records for CVE-2026-39210 through CVE-2026-39218.
At least at the time checked, “a CVE number is shown” and “NVD has details, CPE, CVSS, and scanner-ready metadata” are separate states.
The remaining 12 findings are listed as DFVULN-116 through DFVULN-127.
They cover RTP AV1, RTP JPEG, RTP LATM, RTP MPEG-4, AVIF overlay, CAF, AVI, RTSP server path, RTMP client, and SDP parser paths. depthfirst says they are fixed but do not yet have CVE identifiers.
Fixes without CVEs do not fit cleanly into automated detection.
NVD or SCA tools that depend on CPE matching cannot catch a fix that has no CVE.
As discussed in the NVD enrichment article, even an existing CVE can be missed if CPE metadata is absent.
The unnumbered findings here are one step earlier: they do not even show up in CVE lists, so the distributor’s patch notes become part of the check.
RTSP URL to a 183-byte PoC
The issue depthfirst explains in the most exploit detail is DFVULN-127, a heap buffer overflow in the AV1 over RTP depacketizer.
If FFmpeg is given an attacker-controlled RTSP URL and processes an AV1 RTP payload, the branch that “ignores and removes” a Temporal Delimiter OBU advances only the output cursor.
The following write lands outside the allocated buffer and overwrites FFmpeg’s internal AVBuffer.free function pointer.
In depthfirst’s PoC, a 183-byte RTP packet redirects the instruction pointer to 0xdeadbeef.
This is not a “huge video makes it crash” DoS case.
It occurs during the normal RTSP PLAY phase. No unusual command-line flags, authentication, or extra victim-side interaction are required beyond opening that URL.
The flow looks like this.
flowchart TD
A[Externally supplied RTSP URL] --> B[FFmpeg runs RTSP PLAY]
B --> C[Receives AV1 over RTP packet]
C --> D[Combines AV1 OBUs in order]
D --> E[Branch removes Temporal Delimiter OBU]
E --> F[pktpos advances<br/>output buffer does not grow]
F --> G[Next OBU is written<br/>past allocated memory]
G --> H[Adjacent AVBuffer.free is overwritten]
H --> I[Old buffer is freed<br/>branch through overwritten pointer]
AV1 carries video data in units called OBUs, or Open Bitstream Units.
FFmpeg’s RTP AV1 depacketizer extracts OBUs from RTP packets and repacks them into an output packet.
For ordinary OBUs, FFmpeg grows the output packet before writing, keeping the write position and allocated size aligned.
A Temporal Delimiter OBU is a frame-boundary marker and is removed from the output.
In the vulnerable branch, the code does not emit that OBU, but still advances pktpos, the output-position variable, by the OBU size.
When the next OBU is written, pktpos has already passed the end of the allocated buffer, and the next bytes go into adjacent heap memory.
According to depthfirst, after FFmpeg allocates the packet buffer, an AVBuffer bookkeeping structure can sit nearby. That structure contains a free function pointer used when the buffer is released.
After the overflow rewrites that pointer, another packet-growth operation enters the path that releases the old buffer.
At that point, the overwritten AVBuffer.free callback is invoked, and the instruction pointer moves to the PoC-controlled value.
The deployments closest to this condition are services that accept an external URL, fetch it server-side, and run preview or conversion; surveillance and CCTV systems aggregating RTSP feeds; and transcode workers ingesting remote streams.
Compared with local CLI use on files you own, services that accept public URLs or RTSP URLs and start FFmpeg deserve the first check.
In the HLS extraction and FFmpeg copy mux article, I covered a pipeline that fetches TS segments and feeds them into FFmpeg for MP4 muxing.
In that context, HLS/TS/DASH inputs become the boundary where external data reaches FFmpeg parsers.
These 21 findings are not limited to RTSP; TS and DASH demuxers are in scope too. For services that do not use RTSP, check whether external playlists or segments are passed to FFmpeg.
Checks differ by distributor
As of June 16, 2026, FFmpeg’s security page mentions a rise in AI-generated false-positive reports and asks for human review, reproducible test cases, stack traces, introducing commits, and fix patches.
The page lists Big Sleep-derived CVEs, but did not list CVE-2026-39210 through CVE-2026-39218 or depthfirst by name when checked.
FFmpeg’s download page lists 8.1.1 as the latest stable release, released on May 4, 2026.
depthfirst’s article was published on June 2, 2026, so “update to the latest stable release and all 21 are covered” is not a safe statement.
Master, release branches, distribution backports, and static-build distributors move separately.
ffmpeg -version only covers the binary currently on that path.
The FFmpeg binary on the server PATH, the FFmpeg inside Docker images, static binaries bundled with apps, binaries invoked by Python wheels or Node packages, and embedded libavcodec / libavformat copies inside desktop apps can all be different.
For media workers in particular, a base-image update leaves the old FFmpeg in place until the application image is rebuilt.
For code that accepts external URLs, input restrictions are a separate task from updating FFmpeg.
If forms or APIs accept arbitrary rtsp://, http://, https://, file://, or other protocol URLs, pin the allowed schemes, destinations, timeouts, maximum sizes, codecs, and formats on the server side.
FFmpeg supports many protocols and input formats. Free-form input can become not only a media-parser entry point, but also an SSRF (server-side request forgery) or local-file access path.