From c419542d956a2607bbce5df64b9d378a8588d778 Mon Sep 17 00:00:00 2001
From: Tim Rühsen <tim.ruehsen@gmx.de>
Date: Sun, 27 Oct 2024 19:53:14 +0100
Subject: [PATCH] Fix CVE-2024-10524 (drop support for shorthand URLs)

* doc/wget.texi: Add documentation for removed support for shorthand URLs.
* src/html-url.c (src/html-url.c): Call maybe_prepend_scheme.
* src/main.c (main): Likewise.
* src/retr.c (getproxy): Likewise.
* src/url.c: Rename definition of rewrite_shorthand_url to maybe_prepend_scheme,
  add new function is_valid_port.
* src/url.h: Rename declaration of rewrite_shorthand_url to maybe_prepend_scheme.

Reported-by: Goni Golan <gonig@jfrog.com>

CVE: CVE-2024-10524

Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/wget.git/commit/?id=c419542d956a2607bbce5df64b9d378a8588d778]

Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
---
 doc/wget.texi  | 12 ++++-------
 src/html-url.c |  2 +-
 src/main.c     |  2 +-
 src/retr.c     |  2 +-
 src/url.c      | 57 ++++++++++++++++----------------------------------
 src/url.h      |  2 +-
 6 files changed, 26 insertions(+), 51 deletions(-)

diff --git a/doc/wget.texi b/doc/wget.texi
index 3c24de2..503a03d 100644
--- a/doc/wget.texi
+++ b/doc/wget.texi
@@ -314,8 +314,8 @@ for text files.  Here is an example:
 ftp://host/directory/file;type=a
 @end example
 
-Two alternative variants of @sc{url} specification are also supported,
-because of historical (hysterical?) reasons and their widespreaded use.
+The two alternative variants of @sc{url} specifications are no longer
+supported because of security considerations:
 
 @sc{ftp}-only syntax (supported by @code{NcFTP}):
 @example
@@ -327,12 +327,8 @@ host:/dir/file
 host[:port]/dir/file
 @end example
 
-These two alternative forms are deprecated, and may cease being
-supported in the future.
-
-If you do not understand the difference between these notations, or do
-not know which one to use, just use the plain ordinary format you use
-with your favorite browser, like @code{Lynx} or @code{Netscape}.
+These two alternative forms have been deprecated long time ago,
+and support is removed with version 1.22.0.
 
 @c man begin OPTIONS
 
diff --git a/src/html-url.c b/src/html-url.c
index 896d6fc..3deea9c 100644
--- a/src/html-url.c
+++ b/src/html-url.c
@@ -931,7 +931,7 @@ get_urls_file (const char *file)
           url_text = merged;
         }
 
-      new_url = rewrite_shorthand_url (url_text);
+      new_url = maybe_prepend_scheme (url_text);
       if (new_url)
         {
           xfree (url_text);
diff --git a/src/main.c b/src/main.c
index d1c3c3e..f1d7792 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2126,7 +2126,7 @@ only if outputting to a regular file.\n"));
       struct iri *iri = iri_new ();
       struct url *url_parsed;
 
-      t = rewrite_shorthand_url (argv[optind]);
+      t = maybe_prepend_scheme (argv[optind]);
       if (!t)
         t = argv[optind];
 
diff --git a/src/retr.c b/src/retr.c
index 38c9fcf..a124046 100644
--- a/src/retr.c
+++ b/src/retr.c
@@ -1493,7 +1493,7 @@ getproxy (struct url *u)
 
   /* Handle shorthands.  `rewritten_storage' is a kludge to allow
      getproxy() to return static storage. */
-  rewritten_url = rewrite_shorthand_url (proxy);
+  rewritten_url = maybe_prepend_scheme (proxy);
   if (rewritten_url)
     return rewritten_url;
 
diff --git a/src/url.c b/src/url.c
index 0acd3f3..6868825 100644
--- a/src/url.c
+++ b/src/url.c
@@ -594,60 +594,39 @@ parse_credentials (const char *beg, const char *end, char **user, char **passwd)
   return true;
 }
 
-/* Used by main.c: detect URLs written using the "shorthand" URL forms
-   originally popularized by Netscape and NcFTP.  HTTP shorthands look
-   like this:
-
-   www.foo.com[:port]/dir/file   -> http://www.foo.com[:port]/dir/file
-   www.foo.com[:port]            -> http://www.foo.com[:port]
-
-   FTP shorthands look like this:
-
-   foo.bar.com:dir/file          -> ftp://foo.bar.com/dir/file
-   foo.bar.com:/absdir/file      -> ftp://foo.bar.com//absdir/file
+static bool is_valid_port(const char *p)
+{
+  unsigned port = (unsigned) atoi (p);
+  if (port == 0 || port > 65535)
+    return false;
 
-   If the URL needs not or cannot be rewritten, return NULL.  */
+  int digits = strspn (p, "0123456789");
+  return digits && (p[digits] == '/' || p[digits] == '\0');
+}
 
+/* Prepend "http://" to url if scheme is missing, otherwise return NULL. */
 char *
-rewrite_shorthand_url (const char *url)
+maybe_prepend_scheme (const char *url)
 {
-  const char *p;
-  char *ret;
-
   if (url_scheme (url) != SCHEME_INVALID)
     return NULL;
 
-  /* Look for a ':' or '/'.  The former signifies NcFTP syntax, the
-     latter Netscape.  */
-  p = strpbrk (url, ":/");
+  const char *p = strchr (url, ':');
   if (p == url)
     return NULL;
 
   /* If we're looking at "://", it means the URL uses a scheme we
      don't support, which may include "https" when compiled without
-     SSL support.  Don't bogusly rewrite such URLs.  */
+     SSL support.  Don't bogusly prepend "http://" to such URLs.  */
   if (p && p[0] == ':' && p[1] == '/' && p[2] == '/')
     return NULL;
 
-  if (p && *p == ':')
-    {
-      /* Colon indicates ftp, as in foo.bar.com:path.  Check for
-         special case of http port number ("localhost:10000").  */
-      int digits = strspn (p + 1, "0123456789");
-      if (digits && (p[1 + digits] == '/' || p[1 + digits] == '\0'))
-        goto http;
-
-      /* Turn "foo.bar.com:path" to "ftp://foo.bar.com/path". */
-      if ((ret = aprintf ("ftp://%s", url)) != NULL)
-        ret[6 + (p - url)] = '/';
-    }
-  else
-    {
-    http:
-      /* Just prepend "http://" to URL. */
-      ret = aprintf ("http://%s", url);
-    }
-  return ret;
+  if (p && p[0] == ':' && !is_valid_port (p + 1))
+    return NULL;
+
+
+  fprintf(stderr, "Prepended http:// to '%s'\n", url);
+  return aprintf ("http://%s", url);
 }
 
 static void split_path (const char *, char **, char **);
diff --git a/src/url.h b/src/url.h
index fb9da33..5f99b0a 100644
--- a/src/url.h
+++ b/src/url.h
@@ -128,7 +128,7 @@ char *uri_merge (const char *, const char *);
 
 int mkalldirs (const char *);
 
-char *rewrite_shorthand_url (const char *);
+char *maybe_prepend_scheme (const char *);
 bool schemes_are_similar_p (enum url_scheme a, enum url_scheme b);
 
 bool are_urls_equal (const char *u1, const char *u2);
-- 
2.40.0

