Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libsoup2 for openSUSE:Factory checked in at 2026-03-05 17:13:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libsoup2 (Old) and /work/SRC/openSUSE:Factory/.libsoup2.new.561 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libsoup2" Thu Mar 5 17:13:34 2026 rev:22 rq:1336038 version:2.74.3 Changes: -------- --- /work/SRC/openSUSE:Factory/libsoup2/libsoup2.changes 2026-02-24 15:37:49.484488351 +0100 +++ /work/SRC/openSUSE:Factory/.libsoup2.new.561/libsoup2.changes 2026-03-05 17:14:48.821815574 +0100 @@ -1,0 +2,13 @@ +Wed Feb 25 02:47:08 UTC 2026 - Jonathan Kang <[email protected]> + +- Add libsoup-CVE-2026-1760.patch: server: close the connection + after responsing a request containing... + (bsc#1257597, CVE-2026-1760, glgo#GNOME/libsoup#475). +- Add libsoup-CVE-2026-1467.patch: uri-utils: do host validation + when checking if a GUri is valid + (bsc#1257398, CVE-2026-1467, glgo#GNOME/libsoup#488). +- Add libsoup-CVE-2026-1539.patch: Also remove Proxy-Authorization + header on cross origin redirect + (bsc#1257441, CVE-2026-1539, glgo#GNOME/libsoup#489). + +------------------------------------------------------------------- New: ---- libsoup-CVE-2026-1467.patch libsoup-CVE-2026-1539.patch libsoup-CVE-2026-1760.patch ----------(New B)---------- New: (bsc#1257597, CVE-2026-1760, glgo#GNOME/libsoup#475). - Add libsoup-CVE-2026-1467.patch: uri-utils: do host validation when checking if a GUri is valid New: (bsc#1257398, CVE-2026-1467, glgo#GNOME/libsoup#488). - Add libsoup-CVE-2026-1539.patch: Also remove Proxy-Authorization header on cross origin redirect New: - Add libsoup-CVE-2026-1760.patch: server: close the connection after responsing a request containing... ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libsoup2.spec ++++++ --- /var/tmp/diff_new_pack.1GAA0N/_old 2026-03-05 17:14:50.805898043 +0100 +++ /var/tmp/diff_new_pack.1GAA0N/_new 2026-03-05 17:14:50.805898043 +0100 @@ -98,6 +98,12 @@ Patch35: libsoup2-CVE-2026-2369.patch # PATCH-FIX-UPSTREAM libsoup2-CVE-2026-2708.patch bsc#1258508 [email protected] -- do not allow adding multiple content length values to headers. Patch36: libsoup2-CVE-2026-2708.patch +# PATCH-FIX-UPSTREAM libsoup-CVE-2026-1760.patch bsc#1257597, CVE-2026-1760, glgo#GNOME/libsoup!475 [email protected] -- server: close the connection after responsing a request containing... +Patch37: libsoup-CVE-2026-1760.patch +# PATCH-FIX-UPSTREAM libsoup-CVE-2026-1467.patch bsc#1257398, CVE-2026-1467, glgo#GNOME/libsoup!498 [email protected] -- uri-utils: do host validation when checking if a GUri is valid +Patch38: libsoup-CVE-2026-1467.patch +# PATCH-FIX-UPSTREAM libsoup-CVE-2026-1539.patch bsc#1257441, CVE-2026-1539, glgo#GNOME/libsoup#489 [email protected] -- Also remove Proxy-Authorization header on cross origin redirect +Patch39: libsoup-CVE-2026-1539.patch BuildRequires: glib-networking BuildRequires: meson >= 0.50 ++++++ libsoup-CVE-2026-1467.patch ++++++ Index: libsoup-2.68.4/libsoup/soup-uri.c =================================================================== --- libsoup-2.68.4.orig/libsoup/soup-uri.c +++ libsoup-2.68.4/libsoup/soup-uri.c @@ -1354,6 +1354,68 @@ soup_uri_is_http (SoupURI *uri, char **a return FALSE; } +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_https (SoupURI *uri, char **aliases) { Index: libsoup-2.68.4/libsoup/soup-uri.h =================================================================== --- libsoup-2.68.4.orig/libsoup/soup-uri.h +++ libsoup-2.68.4/libsoup/soup-uri.h @@ -134,6 +134,9 @@ 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) Index: libsoup-2.68.4/libsoup/soup-auth.c =================================================================== --- libsoup-2.68.4.orig/libsoup/soup-auth.c +++ libsoup-2.68.4/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); } Index: libsoup-2.68.4/libsoup/soup-message.c =================================================================== --- libsoup-2.68.4.orig/libsoup/soup-message.c +++ libsoup-2.68.4/libsoup/soup-message.c @@ -1001,7 +1001,7 @@ soup_message_new (const char *method, co 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; } @@ -1023,6 +1023,8 @@ soup_message_new (const char *method, co 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, @@ -1632,6 +1634,7 @@ soup_message_set_uri (SoupMessage *msg, { SoupMessagePrivate *priv; + g_return_if_fail (soup_uri_is_valid (uri)); g_return_if_fail (SOUP_IS_MESSAGE (msg)); priv = soup_message_get_instance_private (msg); ++++++ libsoup-CVE-2026-1539.patch ++++++ Index: libsoup-2.68.4/libsoup/soup-session.c =================================================================== --- libsoup-2.68.4.orig/libsoup/soup-session.c +++ libsoup-2.68.4/libsoup/soup-session.c @@ -1187,6 +1187,7 @@ soup_session_redirect_message (SoupSessi if (!soup_uri_host_equal (soup_message_get_uri (msg), new_uri)) { soup_message_headers_remove (msg->request_headers, "Authorization"); + soup_message_headers_remove (msg->request_headers, "Proxy-Authorization"); soup_message_set_auth (msg, NULL); } Index: libsoup-2.68.4/tests/httpd.conf.in =================================================================== --- libsoup-2.68.4.orig/tests/httpd.conf.in +++ libsoup-2.68.4/tests/httpd.conf.in @@ -37,6 +37,7 @@ DirectoryIndex index.txt TypesConfig /dev/null AddType application/x-httpd-php .php Redirect permanent /redirected /index.txt +Redirect permanent /Basic/realm1/redirected https://127.0.0.1:47525/index.txt # Proxy #1: unauthenticated Listen 127.0.0.1:47526 Index: libsoup-2.68.4/tests/proxy-test.c =================================================================== --- libsoup-2.68.4.orig/tests/proxy-test.c +++ libsoup-2.68.4/tests/proxy-test.c @@ -322,6 +322,39 @@ do_proxy_redirect_test (void) soup_test_session_abort_unref (session); } +static void proxy_auth_redirect_message_restarted (SoupMessage *msg) +{ + if (soup_message_get_status (msg) != SOUP_STATUS_MOVED_PERMANENTLY) + return; + + g_assert_null (soup_message_headers_get_one (soup_message_get_request_headers (msg), "Proxy-Authorization")); +} + +static void +do_proxy_auth_redirect_test (void) +{ + SoupSession *session; + SoupMessage *msg; + char *url; + + SOUP_TEST_SKIP_IF_NO_APACHE; + SOUP_TEST_SKIP_IF_NO_TLS; + + session = soup_test_session_new ("proxy-resolver", proxy_resolvers[AUTH_PROXY], NULL); + + url = g_strconcat (HTTP_SERVER, "/Basic/realm1/redirected", NULL); + msg = soup_message_new (SOUP_METHOD_GET, url); + g_signal_connect (msg, "authenticate", G_CALLBACK (authenticate), NULL); + g_signal_connect (msg, "restarted", G_CALLBACK (proxy_auth_redirect_message_restarted), NULL); + + soup_test_session_send_message (session, msg); + soup_test_assert_message_status (msg, SOUP_STATUS_OK); + + g_free (url); + g_object_unref (msg); + soup_test_session_abort_unref (session); +} + static void do_proxy_auth_request (const char *url, SoupSession *session, gboolean do_read) { @@ -433,6 +466,7 @@ main (int argc, char **argv) g_test_add_data_func ("/proxy/fragment", base_uri, do_proxy_fragment_test); g_test_add_func ("/proxy/redirect", do_proxy_redirect_test); + g_test_add_func ("/proxy/auth-redirect", do_proxy_auth_redirect_test); g_test_add_func ("/proxy/auth-cache", do_proxy_auth_cache_test); ret = g_test_run (); ++++++ libsoup-CVE-2026-1760.patch ++++++ Index: libsoup-2.68.4/libsoup/soup-message-headers.c =================================================================== --- libsoup-2.68.4.orig/libsoup/soup-message-headers.c +++ libsoup-2.68.4/libsoup/soup-message-headers.c @@ -706,38 +706,13 @@ clear_special_headers (SoupMessageHeader static void transfer_encoding_setter (SoupMessageHeaders *hdrs, const char *value) { - if (value) { - /* "identity" is a wrong value according to RFC errata 408, - * and RFC 7230 does not list it as valid transfer-coding. - * Nevertheless, the obsolete RFC 2616 stated "identity" - * as valid, so we can't handle it as unrecognized here - * for compatibility reasons. - */ - if (g_ascii_strcasecmp (value, "chunked") == 0) - hdrs->encoding = SOUP_ENCODING_CHUNKED; - else if (g_ascii_strcasecmp (value, "identity") != 0) - hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; - } else - hdrs->encoding = -1; + hdrs->encoding = -1; } static void content_length_setter (SoupMessageHeaders *hdrs, const char *value) { - /* Transfer-Encoding trumps Content-Length */ - if (hdrs->encoding == SOUP_ENCODING_CHUNKED) - return; - - if (value) { - char *end; - - hdrs->content_length = g_ascii_strtoull (value, &end, 10); - if (*end) - hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; - else - hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH; - } else - hdrs->encoding = -1; + hdrs->encoding = -1; } /** @@ -769,30 +744,50 @@ content_length_setter (SoupMessageHeader SoupEncoding soup_message_headers_get_encoding (SoupMessageHeaders *hdrs) { - const char *header; + const char *content_length; + const char *transfer_encoding; if (hdrs->encoding != -1) return hdrs->encoding; - /* If Transfer-Encoding was set, hdrs->encoding would already - * be set. So we don't need to check that possibility. - */ - header = soup_message_headers_get_one (hdrs, "Content-Length"); - if (header) { - content_length_setter (hdrs, header); - if (hdrs->encoding != -1) - return hdrs->encoding; + /* Transfer-Encoding is check first because it overrides the Content-Length */ + transfer_encoding = soup_message_headers_get_one (hdrs, "Transfer-Encoding"); + if (transfer_encoding) { + /* "identity" is a wrong value according to RFC errata 408, + * and RFC 7230 does not list it as valid transfer-coding. + * Nevertheless, the obsolete RFC 2616 stated "identity" + * as valid, so we can't handle it as unrecognized here + * for compatibility reasons. + */ + if (g_ascii_strcasecmp (transfer_encoding, "chunked") == 0) + hdrs->encoding = SOUP_ENCODING_CHUNKED; + else if (g_ascii_strcasecmp (transfer_encoding, "identity") != 0) + hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; + } else { + content_length = soup_message_headers_get_one (hdrs, "Content-Length"); + if (content_length) { + char *end; + + hdrs->content_length = g_ascii_strtoull (content_length, &end, 10); + if (*end) + hdrs->encoding = SOUP_ENCODING_UNRECOGNIZED; + else + hdrs->encoding = SOUP_ENCODING_CONTENT_LENGTH; + } + } + + if (hdrs->encoding == -1) { + /* Per RFC 2616 4.4, a response body that doesn't indicate its + * encoding otherwise is terminated by connection close, and a + * request that doesn't indicate otherwise has no body. Note + * that SoupMessage calls soup_message_headers_set_encoding() + * to override the response body default for our own + * server-side messages. + */ + hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? + SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; } - /* Per RFC 2616 4.4, a response body that doesn't indicate its - * encoding otherwise is terminated by connection close, and a - * request that doesn't indicate otherwise has no body. Note - * that SoupMessage calls soup_message_headers_set_encoding() - * to override the response body default for our own - * server-side messages. - */ - hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ? - SOUP_ENCODING_EOF : SOUP_ENCODING_NONE; return hdrs->encoding; } Index: libsoup-2.68.4/libsoup/soup-message-server-io.c =================================================================== --- libsoup-2.68.4.orig/libsoup/soup-message-server-io.c +++ libsoup-2.68.4/libsoup/soup-message-server-io.c @@ -80,6 +80,14 @@ parse_request_headers (SoupMessage *msg, return SOUP_STATUS_BAD_REQUEST; } + /* A server MAY reject a request that contains both Content-Length and + * Transfer-Encoding or process such a request in accordance with the + * Transfer-Encoding alone. Regardless, the server MUST close the connection + * after responding to such a request to avoid the potential attacks + */ + if (*encoding == SOUP_ENCODING_CHUNKED && soup_message_headers_get_one (msg->request_headers, "Content-Length")) + soup_message_headers_replace (msg->request_headers, "Connection", "close"); + /* Generate correct context for request */ req_host = soup_message_headers_get_one (msg->request_headers, "Host"); if (req_host && strchr (req_host, '/')) {
