PR #25258 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25258 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25258.patch
Fixes: cookie disclosure to other hosts Fixes: WmqLccCSqIFr Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25035 Cookie disclosure Replicated through UnModified FFmpeg >From 5b3cbbaded2f10825dbde5e11df5bfadeed27f55 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 20 Oct 2026 01:01:18 +0200 Subject: [PATCH] avformat/libcurl: restrict cookies given without a Domain to the host of the URL Fixes: cookie disclosure to other hosts Fixes: WmqLccCSqIFr Found during the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25035 Cookie disclosure Replicated through UnModified FFmpeg --- doc/protocols.texi | 3 ++- libavformat/libcurl.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/doc/protocols.texi b/doc/protocols.texi index 287d972f688..75730e3687a 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -1151,7 +1151,8 @@ Set the HTTP proxy to tunnel through. @item cookies Cookies to be sent in future requests, given as newline-delimited -@code{Set-Cookie}-style values. +@code{Set-Cookie}-style values. A cookie without a domain is sent to the host of +the URL and its subdomains. @item location The actual location of the data after following redirects. This is an output diff --git a/libavformat/libcurl.c b/libavformat/libcurl.c index fc487602db9..0e6d609f7a6 100644 --- a/libavformat/libcurl.c +++ b/libavformat/libcurl.c @@ -1242,6 +1242,25 @@ static int setup_protocols(CurlContext *c) return ret; } +/* Whether a Set-Cookie style line carries a non-empty Domain attribute. */ +static int cookie_has_domain(const char *cookie) +{ + const char *p = cookie; + + while ((p = strchr(p, ';'))) { + p += 1 + strspn(p + 1, " \t"); + if (!av_strncasecmp(p, "domain", 6)) { + const char *v = p + 6 + strspn(p + 6, " \t"); + if (*v == '=') { + v += 1 + strspn(v + 1, " \t."); + if (*v && *v != ';') + return 1; + } + } + } + return 0; +} + #define CURL_SETOPT(opt, val) \ do { \ int ret_ = curl_setopt_checked(c, #opt, \ @@ -1318,25 +1337,45 @@ static int setup_curl(CurlContext *c) } if (c->cookies && c->cookies[0]) { char *copy = av_strdup(c->cookies); - char *line, *saveptr = NULL; + char *line, *saveptr = NULL, *bound; + char host[1024]; + AVBPrint bp; if (!copy) return AVERROR(ENOMEM); + av_url_split(NULL, 0, NULL, 0, host, sizeof(host), NULL, NULL, 0, url); + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); for (line = av_strtok(copy, "\r\n", &saveptr); line; line = av_strtok(NULL, "\r\n", &saveptr)) { - char *sc = av_asprintf("Set-Cookie: %s", line); + int len = strlen(line), has_domain = cookie_has_domain(line); + char *sc; + while (len && (line[len - 1] == ' ' || line[len - 1] == '\t')) + len--; + sc = av_asprintf("Set-Cookie: %.*s%s%s", len, line, + has_domain ? "" : "; domain=", has_domain ? "" : host); if (!sc) { av_free(copy); + av_bprint_finalize(&bp, NULL); return AVERROR(ENOMEM); } cc = curl_easy_setopt(e, CURLOPT_COOKIELIST, sc); + av_bprintf(&bp, "%s\n", sc + sizeof("Set-Cookie: ") - 1); av_free(sc); if ((ret = curl_setopt_checked(c, "CURLOPT_COOKIELIST", cc)) < 0) { av_free(copy); + av_bprint_finalize(&bp, NULL); return ret; } } av_free(copy); + if (!av_bprint_is_complete(&bp)) { + av_bprint_finalize(&bp, NULL); + return AVERROR(ENOMEM); + } + if ((ret = av_bprint_finalize(&bp, &bound)) < 0) + return ret; + av_free(c->cookies); + c->cookies = bound; } if ((ret = build_headers(c)) < 0) -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
