From patchwork Tue May 30 22:52:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 3768 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.10.2 with SMTP id 2csp29305vsk; Tue, 30 May 2017 15:52:33 -0700 (PDT) X-Received: by 10.28.218.3 with SMTP id r3mr3147372wmg.120.1496184753853; Tue, 30 May 2017 15:52:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496184753; cv=none; d=google.com; s=arc-20160816; b=fL1j46YgByvbIhC60ml54zdn/x7tK0dR4GfbquCh+n/QnTnISIq+gxWeHPoTfrL+68 bEKnYzr6G0031aL3L2ujbNHCZKWcitSRe67WKdXNNaHWQ2HPN08ngpbMgEPEnSTYTFLm SmfpWxzwAgMUw0LuNXjYZdwZtAJxNJuQsyXBqiK7ufhmJPgKy0zR6WBkaN36q2E4GL0H EhPQoAGOwaZWB+mNqH5KN5g/9e1ZO6PXsSo7TYMRRfRKcKZXxLx0TjbWLOsCfyXLttZz kKn8BvMdvo/ZbYIkPEiaZbZLecLD1xOPw7aca5ExZcBON+n5BBy54qTmWhHiqvgfKr40 YJ/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:delivered-to :arc-authentication-results; bh=FFgG0fZS91/usNjyYs6+qVd7Y6VFAV3LUjRGQ2wAR3Y=; b=0Eq4IdBmAOR4we74Su8nTUqCwyDu4/sH2LldRie7LR+1TA9u8hctvigeL+aHPXqwTx KletoaPQSR2kSGpwW0QjGJNUNbXo4hAtO+9ik6nZLGiCHMb7kkYRBgVNEdsjZ/BRfakX jrhXUDg4I5kFh2JWfZEOvzpuZ0XN1nmza6uvHkyIEfrz6p/qTC8EjE3zoIZDCUlsTXB3 r9HsuoX1dxIkm5MHqTp0+1wJU4PoxiZs9WgniNgUZBDoQQwp3RbM6NF7d3Cb0RCxy2HV diba3m13CMd/wdXw3QtPCfPppFRauF2gCZc5MsHC8oPrUuy0X5lmgrUSypkQaBuLYs9W CCLA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id v14si15785665wrv.47.2017.05.30.15.52.32; Tue, 30 May 2017 15:52:33 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 425CC6883E2; Wed, 31 May 2017 01:52:25 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vie01a-qmta-pe02-1.mx.upcmail.net (vie01a-qmta-pe02-1.mx.upcmail.net [62.179.121.181]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5AE51680AA2 for ; Wed, 31 May 2017 01:52:19 +0300 (EEST) Received: from [172.31.218.43] (helo=vie01a-dmta-pe05-1.mx.upcmail.net) by vie01a-pqmta-pe02.mx.upcmail.net with esmtp (Exim 4.88) (envelope-from ) id 1dFpzz-00013K-AA for ffmpeg-devel@ffmpeg.org; Wed, 31 May 2017 00:52:23 +0200 Received: from [172.31.216.43] (helo=vie01a-pemc-psmtp-pe01) by vie01a-dmta-pe05.mx.upcmail.net with esmtp (Exim 4.88) (envelope-from ) id 1dFpzt-0003HC-Hv for ffmpeg-devel@ffmpeg.org; Wed, 31 May 2017 00:52:17 +0200 Received: from localhost ([213.47.41.20]) by vie01a-pemc-psmtp-pe01 with SMTP @ mailcloud.upcmail.net id SmsF1v00f0S5wYM01msGyp; Wed, 31 May 2017 00:52:16 +0200 X-SourceIP: 213.47.41.20 From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Wed, 31 May 2017 00:52:14 +0200 Message-Id: <20170530225214.25864-1-michael@niedermayer.cc> X-Mailer: git-send-email 2.13.0 Subject: [FFmpeg-devel] [PATCH] avformat/hls: Disallow local file access by default X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This prevents an exploit leading to an information leak The existing exploit depends on a specific decoder as well. It does appear though that the exploit should be possible with any decoder. The problem is that as long as sensitive information gets into the decoder, the output of the decoder becomes sensitive as well. The only obvious solution is to prevent access to sensitive information. Or to disable hls or possibly some of its feature. More complex solutions like checking the path to limit access to only subdirectories of the hls path may work as an alternative. But such solutions are fragile and tricky to implement portably and would not stop every possible attack nor would they work with all valid hls files. Found-by: Emil Lerner and Pavel Cheremushkin Reported-by: Thierry Foucu Signed-off-by: Michael Niedermayer --- libavformat/hls.c | 13 ++++++++++++- tests/fate/avformat.mak | 4 ++-- tests/fate/filter-audio.mak | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 4b8fb19a52..3a82855ab7 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -204,6 +204,7 @@ typedef struct HLSContext { char *http_proxy; ///< holds the address of the HTTP proxy server AVDictionary *avio_opts; int strict_std_compliance; + int allow_file; } HLSContext; static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) @@ -618,8 +619,16 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, return AVERROR_INVALIDDATA; // only http(s) & file are allowed - if (!av_strstart(proto_name, "http", NULL) && !av_strstart(proto_name, "file", NULL)) + if (av_strstart(proto_name, "http", NULL)) + ; + else if (av_strstart(proto_name, "file", NULL)) { + if (!c->allow_file) { + av_log(s, AV_LOG_ERROR, "Local file access is disabled by default for security reasons. To override this set hls_allow_file to 1\n"); + return AVERROR_INVALIDDATA; + } + } else return AVERROR_INVALIDDATA; + if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':') ; else if (av_strstart(url, "crypto", NULL) && !strncmp(proto_name, url + 7, strlen(proto_name)) && url[7 + strlen(proto_name)] == ':') @@ -2134,6 +2143,8 @@ static int hls_probe(AVProbeData *p) static const AVOption hls_options[] = { {"live_start_index", "segment index to start live streams at (negative values are from the end)", OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS}, + {"hls_allow_file", "Allow to refer to files instead of http only", + OFFSET(allow_file), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS}, {NULL} }; diff --git a/tests/fate/avformat.mak b/tests/fate/avformat.mak index 82a531c7a5..0ca907ab7f 100644 --- a/tests/fate/avformat.mak +++ b/tests/fate/avformat.mak @@ -119,12 +119,12 @@ tests/data/adts-to-mkv-cated-%.mkv: tests/data/adts-to-mkv-header.mkv tests/data FATE_SEGMENT += fate-segment-mp4-to-ts fate-segment-mp4-to-ts: tests/data/mp4-to-ts.m3u8 -fate-segment-mp4-to-ts: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/mp4-to-ts.m3u8 -c copy +fate-segment-mp4-to-ts: CMD = framecrc -flags +bitexact -hls_allow_file 1 -i $(TARGET_PATH)/tests/data/mp4-to-ts.m3u8 -c copy FATE_SEGMENT-$(call ALLYES, MOV_DEMUXER H264_MP4TOANNEXB_BSF MPEGTS_MUXER MATROSKA_DEMUXER SEGMENT_MUXER HLS_DEMUXER) += fate-segment-mp4-to-ts FATE_SEGMENT += fate-segment-adts-to-mkv fate-segment-adts-to-mkv: tests/data/adts-to-mkv.m3u8 -fate-segment-adts-to-mkv: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/adts-to-mkv.m3u8 -c copy +fate-segment-adts-to-mkv: CMD = framecrc -flags +bitexact -hls_allow_file 1 -i $(TARGET_PATH)/tests/data/adts-to-mkv.m3u8 -c copy fate-segment-adts-to-mkv: REF = $(SRC_PATH)/tests/ref/fate/segment-adts-to-mkv-header-all FATE_SEGMENT-$(call ALLYES, AAC_DEMUXER AAC_ADTSTOASC_BSF MATROSKA_MUXER MATROSKA_DEMUXER SEGMENT_MUXER HLS_DEMUXER) += fate-segment-adts-to-mkv diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak index 5d15b31e0b..0c229ccc51 100644 --- a/tests/fate/filter-audio.mak +++ b/tests/fate/filter-audio.mak @@ -150,7 +150,7 @@ tests/data/hls-list.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_AFILTER-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-filter-hls fate-filter-hls: tests/data/hls-list.m3u8 -fate-filter-hls: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls-list.m3u8 +fate-filter-hls: CMD = framecrc -flags +bitexact -hls_allow_file 1 -i $(TARGET_PATH)/tests/data/hls-list.m3u8 tests/data/hls-list-append.m3u8: TAG = GEN tests/data/hls-list-append.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data @@ -164,7 +164,7 @@ tests/data/hls-list-append.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data FATE_AFILTER-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILTER LAVFI_INDEV MP2FIXED_ENCODER) += fate-filter-hls-append fate-filter-hls-append: tests/data/hls-list-append.m3u8 -fate-filter-hls-append: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls-list-append.m3u8 -af asetpts=RTCTIME +fate-filter-hls-append: CMD = framecrc -flags +bitexact -hls_allow_file 1 -i $(TARGET_PATH)/tests/data/hls-list-append.m3u8 -af asetpts=RTCTIME FATE_AMIX += fate-filter-amix-simple fate-filter-amix-simple: CMD = ffmpeg -filter_complex amix -i $(SRC) -ss 3 -i $(SRC1) -f f32le -