From b4f1dcb89a552fc03bfd0e65830b4f76fdc4a232 Mon Sep 17 00:00:00 2001 From: Changqing Li Date: Tue, 21 Apr 2026 17:10:37 +0800 Subject: [PATCH] Fix CVE-2026-1467 CVE: CVE-2026-1467 Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libsoup/-/commit/6dfe506618d2d5856618e5c0f85bd93386dc8012] The original backport patch targets libsoup3. This patch has been adapted accordingly for libsoup2, refer the openSUSE patch, see [1] [1] https://www.suse.com/security/cve/CVE-2026-1467.html Signed-off-by: Changqing Li --- libsoup/soup-auth.c | 2 +- libsoup/soup-message.c | 5 +++- libsoup/soup-uri.c | 60 ++++++++++++++++++++++++++++++++++++++++++ libsoup/soup-uri.h | 2 ++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/libsoup/soup-auth.c b/libsoup/soup-auth.c index 1896aab..e205fe3 100644 --- a/libsoup/soup-auth.c +++ b/libsoup/soup-auth.c @@ -535,7 +535,7 @@ GSList * soup_auth_get_protection_space (SoupAuth *auth, SoupURI *source_uri) { g_return_val_if_fail (SOUP_IS_AUTH (auth), NULL); - g_return_val_if_fail (source_uri != NULL, NULL); + g_return_val_if_fail (soup_uri_is_valid (source_uri), NULL); return SOUP_AUTH_GET_CLASS (auth)->get_protection_space (auth, source_uri); } diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c index da32b42..cc4f22b 100644 --- a/libsoup/soup-message.c +++ b/libsoup/soup-message.c @@ -1044,7 +1044,7 @@ soup_message_new (const char *method, const char *uri_string) uri = soup_uri_new (uri_string); if (!uri) return NULL; - if (!uri->host) { + if (!soup_uri_is_valid (uri)) { soup_uri_free (uri); return NULL; } @@ -1066,6 +1066,8 @@ soup_message_new (const char *method, const char *uri_string) SoupMessage * soup_message_new_from_uri (const char *method, SoupURI *uri) { + g_return_val_if_fail (soup_uri_is_valid (uri), NULL); + return g_object_new (SOUP_TYPE_MESSAGE, SOUP_MESSAGE_METHOD, method, SOUP_MESSAGE_URI, uri, @@ -1676,6 +1678,7 @@ soup_message_set_uri (SoupMessage *msg, SoupURI *uri) SoupMessagePrivate *priv; g_return_if_fail (SOUP_IS_MESSAGE (msg)); + g_return_if_fail (soup_uri_is_valid (uri)); priv = soup_message_get_instance_private (msg); if (priv->uri) diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c index bdb7a17..d781ff1 100644 --- a/libsoup/soup-uri.c +++ b/libsoup/soup-uri.c @@ -1342,6 +1342,66 @@ soup_uri_host_equal (gconstpointer v1, gconstpointer v2) return g_ascii_strcasecmp (one->host, two->host) == 0; } +static gboolean +is_valid_character_for_host (char c) +{ + static const char forbidden_chars[] = { '\t', '\n', '\r', ' ', '#', '/', ':', '<', '>', '?', '@', '[', '\\', ']', '^', '|' }; + int i; + + for (i = 0; i < G_N_ELEMENTS (forbidden_chars); ++i) { + if (c == forbidden_chars[i]) + return FALSE; + } + + return TRUE; +} + +static gboolean +is_host_valid (const char* host) +{ + int i; + gboolean is_valid; + char *ascii_host = NULL; + + if (!host || !host[0]) + return FALSE; + + if (g_hostname_is_non_ascii (host)) { + ascii_host = g_hostname_to_ascii (host); + if (!ascii_host) + return FALSE; + + host = ascii_host; + } + + if ((g_ascii_isdigit (host[0]) || strchr (host, ':')) && g_hostname_is_ip_address (host)) { + g_free (ascii_host); + return TRUE; + } + is_valid = TRUE; + for (i = 0; host[i] && is_valid; i++) + is_valid = is_valid_character_for_host (host[i]); + + g_free (ascii_host); + + return is_valid; +} + +gboolean +soup_uri_is_valid (SoupURI *uri) +{ + if (!uri) + return FALSE; + + if (!is_host_valid (soup_uri_get_host (uri))) + return FALSE; + + /* FIXME: validate other URI components? */ + + return TRUE; +} + + gboolean soup_uri_is_http (SoupURI *uri, char **aliases) { diff --git a/libsoup/soup-uri.h b/libsoup/soup-uri.h index 8015e4f..64099c3 100644 --- a/libsoup/soup-uri.h +++ b/libsoup/soup-uri.h @@ -133,6 +133,8 @@ guint soup_uri_host_hash (gconstpointer key); SOUP_AVAILABLE_IN_2_28 gboolean soup_uri_host_equal (gconstpointer v1, gconstpointer v2); +SOUP_AVAILABLE_IN_2_68 +gboolean soup_uri_is_valid (SoupURI *uri); #define SOUP_URI_IS_VALID(uri) ((uri) && (uri)->scheme && (uri)->path) #define SOUP_URI_VALID_FOR_HTTP(uri) ((uri) && ((uri)->scheme == SOUP_URI_SCHEME_HTTP || (uri)->scheme == SOUP_URI_SCHEME_HTTPS) && (uri)->host && (uri)->path) -- 2.34.1