From e9697d98e7249b0f68a6be040a4f3dcc5bc101fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Sat, 20 Jun 2026 14:39:54 +0200 Subject: [PATCH] Fix server-controlled unbounded MD5 loop in FTP OPIE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * src/ftp-basic.c (ftp_login): Limit the skey sequence to 9999. Report: wget accepts an unbounded server-controlled integer as the iteration count for its OPIE/S-KEY MD5 key-derivation loop. No upper bound is enforced on the sequence number supplied by the server in the FTP challenge line. The value is passed directly to skey_response() as a loop counter, causing wget to perform up to ~2.1 billion full MD5 computations before responding to the authentication challenge. Reported-by: MichaƂ Majchrowicz and Marcin Wyczechowski Upstream commit (GitLab mirror): https://gitlab.com/gnuwget/wget/-/commit/e9697d98e7249b0f68a6be040a4f3dcc5bc101fa --- wget-1.25.0/src/ftp-basic.c +++ wget-1.25.0/src/ftp-basic.c @@ -204,12 +204,11 @@ static const char *skey_head[] = { "331 s/key ", "331 opiekey " }; - size_t i; const char *seed = NULL; - for (i = 0; i < countof (skey_head); i++) + for (size_t i = 0; i < countof (skey_head); i++) { - int l = strlen (skey_head[i]); + size_t l = strlen (skey_head[i]); if (0 == c_strncasecmp (skey_head[i], respline, l)) { seed = respline + l; @@ -222,7 +221,15 @@ int skey_sequence = 0; /* Extract the sequence from SEED. */ for (; c_isdigit (*seed); seed++) - skey_sequence = 10 * skey_sequence + *seed - '0'; + { + skey_sequence = 10 * skey_sequence + *seed - '0'; + if (skey_sequence > 9999) + { + xfree (respline); + return FTPLOGREFUSED; + } + } + if (*seed == ' ') ++seed; else