FFmpeg 21件のゼロデイ、183バイトのAV1 RTP PoC
目次
TL;DR
影響 FFmpegで外部入力の動画・音声・プレイリスト・RTSP URLを処理する環境。depthfirstは21件のうち9件をCVE-2026-39210〜CVE-2026-39218付きとして列挙しているが、NVD/CVE Services側の公開レコードはまだ確認できない
発火点 AV1 over RTPデパケタイザ。攻撃者が制御するRTSPストリームを ffmpeg -i rtsp://... で開く経路から、183バイトのRTPパケットで制御フローに届くPoC
確認 OSパッケージ、コンテナ、静的ビルド、Python/Node/デスクトップアプリに同梱されたFFmpegを別々に確認。CVE一覧だけでなく、公式securityページと配布元のバックポート状況を突き合わせる段階
depthfirstが2026年6月2日に公開した「21 Zero-Days in FFmpeg」には、RTSP URL入力から制御フローに届くPoCまで進んだDFVULN-127が含まれる。
depthfirstの説明と二次報道では、21件のうち9件にCVE番号が付いた扱いになっており、残り12件もdepthfirst側のIDで詳細が出ている。
対象はTSデマルチプレクサ、swscale、DASHデマルチプレクサ、VP9デコーダ、RTP/RTSPまわり、CAF/AVIデマルチプレクサなど、FFmpegの外部入力に近いコードへ散っている。
ここでいうゼロデイは、実際の悪用が確認された0-dayではなく、公開前に発見されて修正・採番の流れに乗った新規脆弱性として扱う。
公開レコード、配布元のバックポート、同梱バイナリの更新はそれぞれ別のタイミングで動く。
前に書いたClaude Mythos Previewの記事では、Anthropicの非公開モデルがFFmpegの16年ものH.264脆弱性を発見した話を扱った。
今回のdepthfirstの発表はそこから一歩進んで、商用の自律セキュリティエージェントが約1,000ドルの実行で21件を出し、少なくとも1件は「クラッシュする入力」ではなく「命令ポインタを取れる入力」まで詰めている。
CVE付きとされる9件と、未採番の12件
depthfirstがCVE付きとして並べているのはCVE-2026-39210からCVE-2026-39218まで。
原典本文には「Eight」と書かれた文が残っているが、列挙されている番号は9個で、The Hacker Newsも9件として扱っている。
内容はヒープバッファオーバーフロー、スタックオーバーフロー、整数オーバーフローが中心だ。
表にすると似た言葉が並ぶが、到達するコード経路はかなり違う。
| ID | 経路 | depthfirstが書いている原因 |
|---|---|---|
| CVE-2026-39210 | TSデマルチプレクサ | 2バイト読み取り前の長さチェック不足 |
| CVE-2026-39211 | swscale | 外部入力パラメータ由来のサイズ計算上限不足 |
| CVE-2026-39212 | ffmpeg_opt.c | プリセットファイルの再帰的なオプション解析に深さ制限なし |
| CVE-2026-39213 | yuv4mpegenc rawvideo | パケットサイズに対する寸法検証不足 |
| CVE-2026-39214 | SDT handling | サービスエントリを書き込む残り容量の追跡不足。2003年由来 |
| CVE-2026-39215 | update_mb_info() | 後続呼び出しで確保済みバッファを12バイト超えて書き込み |
| CVE-2026-39216 | img2enc.c | 安全なchroma sizeを寸法由来サイズへ置換した経路 |
| CVE-2026-39217 | VP9デコーダ | サイズ更新関数のリファクタリングでtile thread bufferの再確保漏れ |
| CVE-2026-39218 | DASHデマルチプレクサ | 負のdurationを拒否せずfragment array indexが負になる |
2026年6月16日時点で、NVD APIとCVE Services APIからはCVE-2026-39210〜CVE-2026-39218の公開レコードを取得できなかった。
少なくとも確認時点では「CVE番号が示されている」ことと「NVDに詳細・CPE・CVSSが入り、スキャナーが拾える」ことを分けて扱う。
残り12件はDFVULN-116〜127として載っている。
RTP AV1、RTP JPEG、RTP LATM、RTP MPEG-4、AVIF overlay、CAF、AVI、RTSP server path、RTMP client、SDP parserなどで、depthfirstは「修正済みだがCVE identifierはまだない」と書いている。
CVEなしの修正は、自動検出の運用に載りにくい。
CVEがない修正は、NVDやSCAツールのCPE照合だけでは拾えない。
以前NVDのenrichment運用変更で書いたように、CVEが存在してもCPEが付かないだけで検出がずれる。
今回の未採番分はその前段で、CVE一覧にすら出ない。配布元のパッチ説明を確認する。
RTSP URLから183バイトPoCに届く
21件の中でdepthfirstが悪用可能性を深く書いているのはDFVULN-127、AV1 over RTPデパケタイザのヒープバッファオーバーフローだ。
攻撃者が制御するRTSP URLをFFmpegに渡し、AV1のRTPペイロード(RTPパケット内のデータ本体)を処理させると、Temporal Delimiter OBUを「無視して取り除く」処理で出力側のカーソルだけが進む。
その後の書き込みが確保済みバッファの外へ飛び、FFmpeg内部の AVBuffer.free 関数ポインタを書き換える。
depthfirstのPoCでは、183バイトのRTPパケットで 0xdeadbeef へ命令ポインタが向く。
これは「巨大な動画を渡すと落ちる」タイプのDoSではない。
FFmpeg側では通常のRTSP PLAY フェーズで、特殊なコマンドラインフラグも不要、認証も不要。被害側の操作は「そのURLを開く」だけだ。
流れはこうなる。
flowchart TD
A[外部から受け取ったRTSP URL] --> B[FFmpegがRTSP PLAYを実行]
B --> C[AV1 over RTPパケットを受信]
C --> D[AV1 OBUを順に結合]
D --> E[Temporal Delimiter OBUを削る分岐]
E --> F[pktposだけ進む<br/>出力バッファは増えない]
F --> G[次のOBUを書き込み<br/>確保済み領域の外へ]
G --> H[隣接するAVBuffer.freeを書き換え]
H --> I[古いバッファ解放時に<br/>書き換え後の関数ポインタへ分岐]
AV1は映像データをOBU(Open Bitstream Unit)という単位で運ぶ。
FFmpegのRTP AV1デパケタイザは、RTPパケット内のOBUを取り出し、出力パケットへ順に詰め直す。
通常のOBUを書き出す前には出力パケットを拡張するので、出力位置と確保済みサイズが揃う。
Temporal Delimiter OBUはフレーム境界用の目印で、出力から取り除かれる。
問題の分岐では、このOBUを出力しないのに、出力位置を示す pktpos だけがOBUサイズ分進む。
次のOBUを書き込む時点で pktpos は確保済みバッファの末尾を越えており、後続の書き込みがヒープ上の隣接領域に入る。
depthfirstの説明では、FFmpegのパケットバッファ確保後に AVBuffer 管理構造体が近くに置かれ、その中に解放時に呼ばれる free 関数ポインタがある。
オーバーフローでこのポインタを書き換えたあと、さらにパケット拡張が走ると古いバッファの解放処理に入る。
その時点で書き換え済みの AVBuffer.free が呼ばれ、命令ポインタがPoC側で指定した値へ向く。
この条件に近いのは、外部から受け取ったURLをサーバー側で取得してプレビューや変換を走らせる機能、監視カメラやCCTVのRTSPフィードを集約する機能、外部ストリームを取り込むトランスコードワーカーあたり。
ローカルで自分の動画だけを変換するCLI用途より、公開URLやRTSP URLを受け取ってFFmpegを起動するサービスを先に確認する。
HLS動画抽出とFFmpeg copy muxの記事では、TSセグメントを取得してFFmpegへ流し、MP4へmuxするパイプラインを扱った。
あの記事の文脈なら、HLS/TS/DASHの入力を自分で取りに行く処理がそのままFFmpegのパーサに外部データを渡す境界になる。
今回の21件はRTSPだけではなくTSデマルチプレクサやDASHデマルチプレクサにも広がっているので、RTSPを使っていないサービスでも「外部プレイリストやセグメントをFFmpegに渡すか」は別に確認する。
配布元ごとに確認が分かれる
2026年6月16日時点で、FFmpeg公式のセキュリティページはAI生成の偽陽性報告増加に触れ、報告には人間レビュー、再現テストケース、スタックトレース、導入コミット、修正パッチなどを求めている。
同ページにはBig Sleep由来のCVEは載っているが、確認時点ではCVE-2026-39210〜39218やdepthfirstの名前の記載はなかった。
公式のダウンロードページでは、最新安定版は8.1.1で、リリース日は2026年5月4日。
depthfirst記事の公開日は2026年6月2日なので、「最新版に上げればこの21件が全部入る」とはまだ書けない。
master、リリースブランチ、ディストリビューションのバックポート、静的ビルド配布者の更新がずれる。
確認は ffmpeg -version だけで済まない。
サーバーのPATHにあるFFmpeg、Dockerイメージ内のFFmpeg、アプリが同梱する静的バイナリ、Python wheelやNode packageが裏で呼ぶバイナリ、デスクトップアプリに埋め込まれたlibavcodec/libavformatがそれぞれ別物になる。
特にメディアワーカー系は、ベースイメージ更新後にアプリイメージをリビルドしないと古いFFmpegが残る。
外部URLを受け取る処理では、FFmpegの更新と別に入力制限も入れる。
入力フォームやAPIで任意の rtsp://、http://、https://、file://、プロトコル付きURLを受け取っているなら、許可スキーム、到達先、タイムアウト、最大サイズ、コーデックやフォーマットの許可リストをサーバー側で固定する。
FFmpegは多くのプロトコルと入力形式を扱える。入力を自由にすると、メディアパーサだけでなくSSRF(サーバー側リクエストフォージェリ)やローカルファイルアクセスの入口にもなる。