FFmpeg에서 발견된 21개 제로데이 — 2026년 6월 보안 현장
2026년 6월, 전 세계 브라우저와 스트리밍 인프라가 의존하는 FFmpeg에서 자율 보안 에이전트가 21개 제로데이를 발견했다. 약 150만 줄의 C 코드에서 약 1천 달러 비용으로, Anthropic Mythos의 10% 수준이다. FFmpeg 23년 묵은 결함을 포함해 9개 CVE가 할당되었고, AV1 RTP depacketizer 단일 결함은 183바이트 패킷으로 PC 제어권을 뺏는다. 본문에서는 발견된 21개 항목의 분류, 가장 위험한 AV1 RTP 경로의 동작, 운영자가 즉시 채택할 수 있는 샌드박싱 가드레일을 정리한다.

FFmpeg 보안 에이전트가 21개를 찾는 방식
depthfirst의 보안 에이전트는 코딩 에이전트와 같은 기반 모델을 쓰지만 목표가 다르다. 사람 과제를 받아 코드를 작성하는 대신, 기존 시스템에서 실제 악용 가능한 보안 이슈를 찾는다. 먼저 코드베이스 아키텍처와 노출된 파서, 공격자 제어 입력의 진입 지점을 파악한다. 이후 평면적인 파일 묶음이 아니라 공격 표면 코드에서 관련 구성요소를 따라 데이터 흐름을 추적한다.
실용적인 가드레일이 핵심이다. 누락된 조건을 꾸며내거나, 이론적 버그를 과장하거나, 오탐을 대량으로 내지 못하게 막는다. 공격자가 실제로 입력을 제어하는지, 취약 경로에 도달 가능한지, 의심되는 결함이 재현 가능한지 확인한다. 필요한 경우 대상 구성요소와 상호작용하는 하네스를 식별하거나 생성해 가설을 시험한다. 결과물은 이론 보고서가 아니라 재현 가능한 입력으로 실행 확인된 보안 이슈다.
에이전트는 총 21개 제로데이를 발견했고, 범위는 TS demuxer부터 VP9 decoder까지 넓다. TS demuxer의 CVE-2026-39210, swscale 리팩터링의 CVE-2026-39211, DASH demuxer의 CVE-2026-39218까지 9개 CVE가 공식 할당됐다. 전체 비용은 약 1천 달러였고, 이는 Anthropic이 Mythos 사용에 쓴 비용의 10%다.
9개 CVE와 12개 DFVULN의 분포
CVE가 할당된 9개 중 7개는 한 세대 넘게 잠재 상태로 머문 결함이다. CVE-2026-39214는 SDT 구현에서 남은 공간을 추적하지 않고 서비스 엔트리를 쓰는 스택 버퍼 오버플로로, 23년 만에 드러났다. CVE-2026-39212는 프리셋 파일이 깊이 제한 없이 옵션 파싱을 재귀적으로 트리거하는 스택 오버플로로, 최근 회귀다. CVE-2026-39217은 VP9 decoder의 리팩터링된 크기 업데이트 함수가 타일 스레드 버퍼 재할당을 놓치는 회귀다.
내부 추적 ID로 참조된 12개 DFVULN은 RTP/RTSP/RTMP 처리 경로에 집중된다. DFVULN-127은 RTP AV1 depacketizer의 Temporal Delimiter 처리 결함이다. DFVULN-123은 RTP LATM depacketizer의 부호 있는 32비트 덧셈 오버플로다. DFVULN-121은 CAF demuxer의 read_seek()가 av_index_search_timestamp()의 반환값 -1을 검사하지 않는 힙 버퍼 언더플로다. DFVULN-118은 RTSP server 경로의 음수 Content-Length 처리 결함이다. RTP LATM, RTP MPEG-4, RTP JPEG depacketizer와 RTSP SDP 파서가 모두 같은 부류의 입력 경계 검사 누락을 보인다.
183바이트로 PC 제어권을 뺏는 AV1 RTP 경로

21개 중 AV1 RTP depacketizer의 힙 버퍼 오버플로가 가장 위험하다. 네트워크에서 특수 플래그 없이 도달 가능하고, 피해자는 ffmpeg -i rtsp://attacker/stream만 실행하면 된다. 단일 183바이트 RTP 패킷으로 실행 흐름이 바뀐다.
depacketizer는 출력 패킷을 점진적으로 만들며, pktpos 커서가 pkt->data 안에서 다음 바이트를 쓸 위치를 추적한다. 코드가 패킷 안의 OBU element를 순회할 때 실제로 내보내는 모든 바이트 앞에는 av_grow_packet 호출이 붙고, 이 호출이 pkt->data의 힙 할당을 키운다. 전체 루틴이 의존하는 불변식은 pktpos가 pkt->data의 할당 크기보다 앞서 나가면 안 된다는 점이다.
Temporal Delimiter 처리 코드가 이 불변식을 깨뜨린다. TD의 obu_size가 148이면 pktpos는 148이 되지만, pkt->data는 여전히 할당되지 않았거나 148바이트보다 훨씬 작을 수 있다. 다음 정상 OBU에서 패킷은 해당 OBU 크기만큼만 커진다. 조작된 OBU가 17바이트이면 av_grow_packet은 81바이트 버퍼를 할당한다. 쓰기는 pkt->data[148]에서 시작해 할당 끝보다 67바이트 뒤에서 발생한다.
av_grow_packet이 av_buffer_alloc을 거치면 데이터 버퍼, AVBuffer bookkeeping struct, AVBufferRef가 순서대로 힙에 할당된다. 81바이트 데이터 버퍼는 128바이트 chunk를 차지하고 AVBuffer struct가 바로 뒤에 놓인다. AVBuffer.free 포인터는 오프셋 152에 위치한다. 익스플로잇은 TD payload 안에 세 번째 조작 OBU를 넣어 한 번 더 av_grow_packet을 발생시킨다. 덮어쓴 free 포인터가 호출되면 release build에서 rip이 0xdeadbeef로 만들어진다.
즉시 채택할 운영자용 가드레일
첫째, FFmpeg를 신뢰할 수 없는 입력으로 실행하는 모든 경로는 샌드박스 외부에서 동작해서는 안 된다. 사용자 제공 stream URL을 가져오는 미디어 ingest pipeline, RTSP 피드를 가져오는 surveillance/CCTV 시스템, 원격 AV1-over-RTP 소스를 처리하는 transcoding 서비스가 영향 범위에 해당한다. 인증이나 스트림 열기 이상의 사용자 상호작용이 필요하지 않으며, 특이한 command-line flag도 필요 없다.
둘째, FFmpeg 자체를 샌드박싱하는 건 어렵지 않지만, FFmpeg를 쓰는 MPV/VLC 같은 경우는 더 까다롭다. Chromium처럼 FFmpeg를 격리하고 seccomp로 강하게 묶는 방식이 필요하다. 최근까지는 virtio GPU 네이티브 컨텍스트가 없어서 하드웨어 가속을 전부 잃지 않고 비디오 플레이어를 샌드박싱하는 것조차 불가능했다.
셋째, FFmpeg를 VM이나 gVisor 안에서 실행하는 게 현실적 선택이다. 최종 결과물은 보통 브라우저에서 재생할 의향이 있는 비디오 파일이다. 브라우저에서도 또 다른 샌드박스 안에서 디코딩된다. 다만 인코딩에는 하드웨어 가속기가 필요한 경우가 많아서, 결국 다시 C를 써야 하는 경우가 흔하다. 2026년 6월 현재 FFmpeg는 대형 미디어 처리의 사실상 표준이다. 완전한 대체는 어렵다. 샌드박싱이 가장 현실적인 가드레일이다.
'자동화&툴 리뷰' 카테고리의 다른 글
| 내 홈랩 AI 개발 플랫폼 — OpenCode와 GitOps로 안전하게 자동화하기 (0) | 2026.06.17 |
|---|---|
| Show GN: tradingcodex - 코덱스를 자산운용사로 만들어주는 하네스 (0) | 2026.06.17 |
| 오픈소스 AI는 반드시 이겨야 한다 — 운영의 자유를 지키는 인프라 (0) | 2026.06.15 |
| Show GN: Claude Code, Codex 스킬 평가용 rubric evaluator 실전 가이드 (0) | 2026.06.13 |
| SlopGuard – AI 슬롭 PR/이슈를 격리하는 GitHub 앱 실전 가이드 (0) | 2026.06.12 |