PR #25035 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25035
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25035.patch

Fixes: cookie disclosure to other hosts
Fixes: u2ys08MO8oEF
Cookie disclosure Replicated through UnModified FFmpeg

Found-by: Yazan Balawneh, Cystack.ps



>From 27f582bcf2c42df0c6602e5c0226ae7e6a198cdc Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 12 Oct 2026 04:12:37 +0200
Subject: [PATCH] avformat/http: send cookies given without a Domain only to
 their host

Fixes: cookie disclosure to other hosts
Fixes: u2ys08MO8oEF
Cookie disclosure Replicated through UnModified FFmpeg

Found-by: Yazan Balawneh, Cystack.ps
---
 doc/protocols.texi |  3 ++-
 libavformat/http.c | 31 +++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/doc/protocols.texi b/doc/protocols.texi
index 7812d154db..c208405d65 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -524,7 +524,8 @@ Exports the HTTP response version number. Usually "1.0" or 
"1.1".
 @item cookies
 Set the cookies to be sent in future requests. The format of each cookie is the
 same as the value of a Set-Cookie HTTP response field. Multiple cookies can be
-delimited by a newline character.
+delimited by a newline character. A cookie without a Domain attribute is only
+sent to the host of the URL it is set for.
 
 @item icy
 If set to 1 request ICY (SHOUTcast) metadata from the server. If the server
diff --git a/libavformat/http.c b/libavformat/http.c
index 488a8eb73d..5e140b2705 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -239,6 +239,7 @@ static int http_connect(URLContext *h, const char *path, 
const char *local_path,
                         const char *hoststr, const char *auth,
                         const char *proxyauth);
 static int http_read_header(URLContext *h);
+static int bind_cookies_to_host(HTTPContext *s);
 static int http_shutdown(URLContext *h, int flags);
 
 void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
@@ -837,6 +838,9 @@ static int http_open(URLContext *h, const char *uri, int 
flags,
     if (!s->uri)
         return AVERROR(ENOMEM);
 
+    if (s->cookies && (ret = bind_cookies_to_host(s)) < 0)
+        return ret;
+
     if (options)
         av_dict_copy(&s->chained_options, *options, 0);
 
@@ -1259,6 +1263,33 @@ static int parse_cookie(HTTPContext *s, const char *p, 
const char *host,
     return 0;
 }
 
+/* Cookies without a Domain apply only to the host they are given for. */
+static int bind_cookies_to_host(HTTPContext *s)
+{
+    char host[1024], *cookies, *cookie, *next, *saveptr = NULL;
+    AVBPrint bp;
+
+    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), NULL, NULL, 0, 
s->location);
+
+    next = cookies = av_strdup(s->cookies);
+    if (!cookies)
+        return AVERROR(ENOMEM);
+
+    av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
+    while ((cookie = av_strtok(next, "\n", &saveptr))) {
+        AVDictionary *params = NULL;
+        int host_only = !parse_set_cookie(cookie, &params) && 
!cookie_domain(params) &&
+                        !av_dict_get(params, "@hostonly", NULL, 0);
+
+        next = NULL;
+        av_dict_free(&params);
+        av_bprintf(&bp, "%s%s%s\n", cookie, host_only ? "; @hostonly=" : "", 
host_only ? host : "");
+    }
+    av_free(cookies);
+    av_freep(&s->cookies);
+    return av_bprint_finalize(&bp, &s->cookies);
+}
+
 static int cookie_string(AVDictionary *dict, char **cookies)
 {
     const AVDictionaryEntry *e = NULL;
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to