File wget-do-not-propagate-credentials.patch of Package wget.37321

From 6a023c8a63cb87020826b62e834da5d6760b9029 Mon Sep 17 00:00:00 2001
From: vlefebvre <valentin.lefebvre@suse.com>
Date: Wed, 4 Dec 2024 18:18:41 +0100
Subject: [PATCH] Discard Authentication and Cookie header

* src/http.c: (unredirectable_headerline) check if a header line is
  included in a list of value that cannot be sent after a redirect.
* src/http.c: (get_http) Do not set user header, when
  location_changed, from unredirectable_headerline.
* src/http.h: (http_loop) Add argument location_changed.

Fix CVE-2021-31879. If wget for an http URL is redirected to a
different site (hostnameparts of URLs differ), then any "Authenticate" and
"Cookie" header entries are discarded.

Signed-off-by: vlefebvre <valentin.lefebvre@suse.com>
---
 src/http.c | 42 ++++++++++++++++++++++++++++++++++++++----
 src/http.h |  2 +-
 src/retr.c |  4 ++--
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/src/http.c b/src/http.c
index 07af1867..383321cb 100644
--- a/src/http.c
+++ b/src/http.c
@@ -3149,6 +3149,31 @@ fail:
 }
 #endif /* HAVE_METALINK */
 
+/*
+ * Check if the corresponding header line should not
+ * be sent after a redirect
+ */
+static bool
+unredirectable_headerline(char *line)
+{
+  static const struct {
+    size_t len;
+    const char *name;
+  } field_name[] = {
+    { 14, "Authorization:" },
+    { 7, "Cookie:" }
+  };
+
+  /*
+   * Note: According to RFC 2616, Field names are case-insensitive.
+   */
+  for (unsigned i = 0; i < countof(field_name); i++)
+    if (c_strncasecmp(line, field_name[i].name, field_name[i].len) == 0)
+      return true;
+
+  return false;
+}
+
 /* Retrieve a document through HTTP protocol.  It recognizes status
    code, and correctly handles redirections.  It closes the network
    socket.  If it receives an error from the functions below it, it
@@ -3161,7 +3186,7 @@ fail:
    server, and u->url will be requested.  */
 static uerr_t
 gethttp (const struct url *u, struct url *original_url, struct http_stat *hs,
-         int *dt, struct url *proxy, struct iri *iri, int count)
+         int *dt, struct url *proxy, struct iri *iri, int count, bool location_changed)
 {
   struct request *req = NULL;
 
@@ -3305,7 +3330,16 @@ gethttp (const struct url *u, struct url *original_url, struct http_stat *hs,
     {
       int i;
       for (i = 0; opt.user_headers[i]; i++)
-        request_set_user_header (req, opt.user_headers[i]);
+	{
+	 /*
+	  * IF we have been redirected
+	  * AND the user-supplied header line should NOT be sent to the new host
+	  * DO NOT append that header line
+	  */
+	 if (location_changed && unredirectable_headerline(opt.user_headers[i]))
+	   continue;
+	 request_set_user_header (req, opt.user_headers[i]);
+	}
     }
 
   proxyauth = NULL;
@@ -4230,7 +4264,7 @@ check_retry_on_http_error (const int statcode)
 uerr_t
 http_loop (const struct url *u, struct url *original_url, char **newloc,
            char **local_file, const char *referer, int *dt, struct url *proxy,
-           struct iri *iri)
+           struct iri *iri, bool location_changed)
 {
   int count;
   bool got_head = false;         /* used for time-stamping and filename detection */
@@ -4417,7 +4451,7 @@ http_loop (const struct url *u, struct url *original_url, char **newloc,
         *dt &= ~SEND_NOCACHE;
 
       /* Try fetching the document, or at least its head.  */
-      err = gethttp (u, original_url, &hstat, dt, proxy, iri, count);
+      err = gethttp (u, original_url, &hstat, dt, proxy, iri, count, location_changed);
 
       /* Time?  */
       tms = datetime_str (time (NULL));
diff --git a/src/http.h b/src/http.h
index 570f7683..55f9b82f 100644
--- a/src/http.h
+++ b/src/http.h
@@ -36,7 +36,7 @@ as that of the covered work.  */
 struct url;
 
 uerr_t http_loop (const struct url *, struct url *, char **, char **, const char *,
-                  int *, struct url *, struct iri *);
+                  int *, struct url *, struct iri *, bool);
 void save_cookies (void);
 void http_cleanup (void);
 time_t http_atotm (const char *);
diff --git a/src/retr.c b/src/retr.c
index 26eb9f17..3d82a44a 100644
--- a/src/retr.c
+++ b/src/retr.c
@@ -874,7 +874,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
 {
   uerr_t result;
   char *url;
-  bool location_changed;
+  bool location_changed = 0;
   bool iri_fallbacked = 0;
   int dummy;
   char *mynewloc, *proxy;
@@ -971,7 +971,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
 	}
 #endif
       result = http_loop (u, orig_parsed, &mynewloc, &local_file, refurl, dt,
-                          proxy_url, iri);
+                          proxy_url, iri, location_changed);
     }
   else if (u->scheme == SCHEME_FTP
 #ifdef HAVE_SSL
-- 
2.43.0

openSUSE Build Service is sponsored by