CVE-2024-24806 (published 2024-02-07T22:15Z)

libuv is a multi-platform support library with a focus on asynchronous I/O. The `uv_getaddrinfo` function in `src/unix/getaddrinfo.c` (and its windows counterpart `src/win/getaddrinfo.c`), truncates hostnames to 256 characters before calling `getaddrinfo`. This behavior can be exploited to create addresses like `0x00007f000001`, which are considered valid by `getaddrinfo` and could allow an attacker to craft payloads that resolve to unintended IP addresses, bypassing developer checks. The vulnerability arises due to how the `hostname_ascii` variable (with a length of 256 bytes) is handled in `uv_getaddrinfo` and subsequently in `uv__idna_toascii`. When the hostname exceeds 256 characters, it gets truncated without a terminating null byte. As a result attackers may be able to access internal APIs or for websites (similar to MySpace) that allows users to have `username.example.com` pages. Internal services that crawl or cache these user pages can be exposed to SSRF attacks if a malicious user chooses a long vulnerable username. This issue has been addressed in release version 1.48.0. Users are advised to upgrade. There are no known workarounds for this vulnerability.

CVSS v3 base score: 7.3, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L)

Weakness information:
cwe_id: CWE-918
cwe_name: Server-Side Request Forgery (SSRF)
description: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
extended_description: By providing URLs to unexpected hosts or ports, attackers can make it appear that the server is sending the request, possibly bypassing access controls such as firewalls that prevent the attackers from accessing the URLs directly. The server can be used as a proxy to conduct port scanning of hosts in internal networks, use other URLs such as that can access documents on the system (using file://), or use other protocols such as gopher:// or tftp://, which may provide greater control over the contents of requests.
         

Fix information:
repo_url: https://github.com/libuv/libuv
commit_details: repo_url: https://github.com/libuv/libuv
author: Ben Noordhuis
author_date: 2024-01-18 14:51:40+01:00
msg: fix: always zero-terminate idna output

Fixes: https://github.com/libuv/libuv/security/advisories/GHSA-f74f-cvh7-c6q6
repository: repo_url: https://github.com/libuv/libuv
repo_name: libuv/libuv
description: Cross-platform asynchronous I/O
repo_language: C
owner: libuv
file_changes: filename: idna.c
change_type: ModificationType.MODIFY
diff: @@ -356,9 +356,10 @@ ssize_t uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
       return rc;
   }
 
-  if (d < de)
-    *d++ = '\0';
+  if (d >= de)
+    return UV_EINVAL;
 
+  *d++ = '\0';
   return d - ds;  /* Number of bytes written. */
 }
 

programming_language: C
filename: test-idna.c
change_type: ModificationType.MODIFY
diff: @@ -100,6 +100,7 @@ TEST_IMPL(utf8_decode1) {
 TEST_IMPL(utf8_decode1_overrun) {
   const char* p;
   char b[1];
+  char c[1];
 
   /* Single byte. */
   p = b;
@@ -113,6 +114,9 @@ TEST_IMPL(utf8_decode1_overrun) {
   ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + 1));
   ASSERT_PTR_EQ(p, b + 1);
 
+  b[0] = 0x7F;
+  ASSERT_EQ(UV_EINVAL, uv__idna_toascii(b, b + 1, c, c + 1));
+
   return 0;
 }
 

programming_language: C
repo_url: https://github.com/libuv/libuv
commit_details: repo_url: https://github.com/libuv/libuv
author: Ben Noordhuis
author_date: 2024-01-18 14:52:38+01:00
msg: fix: reject zero-length idna inputs

Fixes: https://github.com/libuv/libuv/security/advisories/GHSA-f74f-cvh7-c6q6
repository: repo_url: https://github.com/libuv/libuv
repo_name: libuv/libuv
description: Cross-platform asynchronous I/O
repo_language: C
owner: libuv
file_changes: filename: idna.c
change_type: ModificationType.MODIFY
diff: @@ -322,6 +322,9 @@ ssize_t uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
   char* ds;
   int rc;
 
+  if (s == se)
+    return UV_EINVAL;
+
   ds = d;
 
   si = s;

programming_language: C
filename: test-idna.c
change_type: ModificationType.MODIFY
diff: @@ -115,6 +115,7 @@ TEST_IMPL(utf8_decode1_overrun) {
   ASSERT_PTR_EQ(p, b + 1);
 
   b[0] = 0x7F;
+  ASSERT_EQ(UV_EINVAL, uv__idna_toascii(b, b + 0, c, c + 1));
   ASSERT_EQ(UV_EINVAL, uv__idna_toascii(b, b + 1, c, c + 1));
 
   return 0;

programming_language: C
repo_url: https://github.com/libuv/libuv
commit_details: repo_url: https://github.com/libuv/libuv
author: Ben Noordhuis
author_date: 2024-02-07 20:53:55+01:00
msg: Merge pull request from GHSA-f74f-cvh7-c6q6

* fix: always zero-terminate idna output

* fix: reject zero-length idna inputs

* test: empty strings are not valid IDNA

---------

Co-authored-by: Santiago Gimeno <santiago.gimeno@gmail.com>
repository: repo_url: https://github.com/libuv/libuv
repo_name: libuv/libuv
description: Cross-platform asynchronous I/O
repo_language: C
owner: libuv
repo_url: https://github.com/libuv/libuv
commit_details: repo_url: https://github.com/libuv/libuv
author: Santiago Gimeno
author_date: 2024-02-07 20:27:58+01:00
msg: test: empty strings are not valid IDNA

Fixes: https://github.com/libuv/libuv/security/advisories/GHSA-f74f-cvh7-c6q6
repository: repo_url: https://github.com/libuv/libuv
repo_name: libuv/libuv
description: Cross-platform asynchronous I/O
repo_language: C
owner: libuv
file_changes: filename: test-idna.c
change_type: ModificationType.MODIFY
diff: @@ -151,8 +151,8 @@ TEST_IMPL(idna_toascii) {
   /* Illegal inputs. */
   F("\xC0\x80\xC1\x80", UV_EINVAL);  /* Overlong UTF-8 sequence. */
   F("\xC0\x80\xC1\x80.com", UV_EINVAL);  /* Overlong UTF-8 sequence. */
+  F("", UV_EINVAL);
   /* No conversion. */
-  T("", "");
   T(".", ".");
   T(".com", ".com");
   T("example", "example");

programming_language: C