From c419542d956a2607bbce5df64b9d378a8588d778 Mon Sep 17 00:00:00 2001 From: Tim Rühsen Date: Sun, 27 Oct 2024 19:53:14 +0100 Subject: 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 --- 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 1d026d72..d46da375 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 8e960092..99914943 100644 --- a/src/html-url.c +++ b/src/html-url.c @@ -932,7 +932,7 @@ get_urls_file (const char *file, bool *read_again) 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 77b1a0b6..6858d2da 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 5422963c..26eb9f17 100644 --- a/src/retr.c +++ b/src/retr.c @@ -1546,7 +1546,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 07c3bc87..2f27c48a 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 2dfbf30b..7796a21c 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); -- cgit v1.2.3-70-g09d2