From cecdea95801630c87ef1cc502437fedc608631bd Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
Date: Fri, 10 Jul 2026 08:55:09 -0500
Subject: [PATCH] Fix address bar spoofing when userinfo contains : character

Our algorithm for finding the host component of the URL without using a
URL parser is easily defeated by a colon in the userinfo section.
Tighten this up.

It's a real shame that we cannot use a normal URL parser here. But the
goal is to return a pointer into the original string, without mutating
it, so that's not an option.

Fixes #2897


(cherry picked from commit 0dde1d369458ac5c44b74b5ad3c433f825f6f8af)

Co-authored-by: Michael Catanzaro <mcatanzaro@gnome.org>
---
 lib/ephy-uri-helpers.c        |  7 ++++---
 tests/ephy-uri-helpers-test.c | 16 +++++++++++++++-
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/lib/ephy-uri-helpers.c b/lib/ephy-uri-helpers.c
index aa11edb43..a67005741 100644
--- a/lib/ephy-uri-helpers.c
+++ b/lib/ephy-uri-helpers.c
@@ -96,11 +96,12 @@ ephy_uri_get_base_domain (const char *hostname)
 static const char *
 get_first_colon_after_host (const char *authority_start)
 {
-  const char *search_start = authority_start;
+  const char *userinfo_end = strchr (authority_start, '@');
+  const char *search_start = userinfo_end ? userinfo_end + 1 : authority_start;
 
   /* Skip colons in IPv6 addresses */
-  if (authority_start[0] == '[') {
-    const char *bracket_close = strchr (authority_start, ']');
+  if (search_start[0] == '[') {
+    const char *bracket_close = strchr (search_start, ']');
     if (bracket_close)
       search_start = bracket_close;
   }
diff --git a/tests/ephy-uri-helpers-test.c b/tests/ephy-uri-helpers-test.c
index daf5b7180..b800419db 100644
--- a/tests/ephy-uri-helpers-test.c
+++ b/tests/ephy-uri-helpers-test.c
@@ -30,12 +30,25 @@ test_ephy_uri_decode (void)
 
   result = ephy_uri_decode ("https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8");
   g_assert_cmpstr (result, ==, "https://ja.wikipedia.org/wiki/メインページ");
-
   g_clear_pointer (&result, g_free);
+
   result = ephy_uri_decode ("https://xn--9dbaqfu.xn--4dbrk0ce/");
   g_assert_cmpstr (result, ==, "https://כולנו.ישראל/");
 }
 
+static void
+test_ephy_uri_get_decoded_host (void)
+{
+  g_autofree char *result = NULL;
+
+  result = ephy_uri_get_decoded_host ("https://example.com:80@www.gnome.org/");
+  g_assert_cmpstr (result, ==, "www.gnome.org");
+  g_clear_pointer (&result, g_free);
+
+  result = ephy_uri_get_decoded_host ("https://[::1]:8080/");
+  g_assert_cmpstr (result, ==, "[::1]");
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -45,6 +58,7 @@ main (int   argc,
   g_test_init (&argc, &argv, NULL);
 
   g_test_add_func ("/lib/ephy-uri-helpers/decode", test_ephy_uri_decode);
+  g_test_add_func ("/lib/ephy-uri-helpers/get-decoded-host", test_ephy_uri_get_decoded_host);
 
   ret = g_test_run ();
 
-- 
GitLab
