diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2015-07-15 12:18:52 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2015-07-15 12:47:09 +0200 |
commit | 8f2c045a0e21559c0cdec44805bdc26457658f9c (patch) | |
tree | d97822e404dc6c481dd545a9459ec3939e935a05 | |
parent | eea08efc0df3cc488bcbcdb844fc50ac3d87ec5b (diff) | |
download | ffmpeg-8f2c045a0e21559c0cdec44805bdc26457658f9c.tar.gz |
avformat/mov: Implement a same origin policy for references instead of only allowing a subset of relative pathes in references
Fixes Ticket4671
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavformat/mov.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 94fc25dfbb..9d6b2e4f21 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2698,6 +2698,35 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } } +static int test_same_origin(const char *src, const char *ref) { + char src_proto[64]; + char ref_proto[64]; + char src_auth[256]; + char ref_auth[256]; + char src_host[256]; + char ref_host[256]; + int src_port=-1; + int ref_port=-1; + + av_url_split(src_proto, sizeof(src_proto), src_auth, sizeof(src_auth), src_host, sizeof(src_host), &src_port, NULL, 0, src); + av_url_split(ref_proto, sizeof(ref_proto), ref_auth, sizeof(ref_auth), ref_host, sizeof(ref_host), &ref_port, NULL, 0, ref); + + if (strlen(src) == 0) { + return -1; + } else if (strlen(src_auth) + 1 >= sizeof(src_auth) || + strlen(ref_auth) + 1 >= sizeof(ref_auth) || + strlen(src_host) + 1 >= sizeof(src_host) || + strlen(ref_host) + 1 >= sizeof(ref_host)) { + return 0; + } else if (strcmp(src_proto, ref_proto) || + strcmp(src_auth, ref_auth) || + strcmp(src_host, ref_host) || + src_port != ref_port) { + return 0; + } else + return 1; +} + static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref, AVIOInterruptCB *int_cb) { @@ -2738,12 +2767,23 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr av_strlcat(filename, "../", sizeof(filename)); av_strlcat(filename, ref->path + l + 1, sizeof(filename)); - if (!c->use_absolute_path && !c->fc->open_cb) + if (!c->use_absolute_path && !c->fc->open_cb) { + int same_origin = test_same_origin(src, filename); + + if (!same_origin) { + av_log(c->fc, AV_LOG_ERROR, + "Reference with mismatching origin, %s not tried for security reasons, " + "set demuxer option use_absolute_path to allow it anyway\n", + ref->path); + return AVERROR(ENOENT); + } + if(strstr(ref->path + l + 1, "..") || strstr(ref->path + l + 1, ":") || - ref->nlvl_from > 1 || + (ref->nlvl_from > 1 && same_origin < 0) || (filename[0] == '/' && src_path == src)) return AVERROR(ENOENT); + } if (strlen(filename) + 1 == sizeof(filename)) return AVERROR(ENOENT); |