File libsoup-CVE-2026-1760.patch of Package libsoup.42965

From 6224df5a471e9040a99dd3dc2e91817a701b1bf6 Mon Sep 17 00:00:00 2001
From: Carlos Garcia Campos <cgarcia@igalia.com>
Date: Thu, 29 Jan 2026 16:43:28 +0100
Subject: [PATCH] server: close the connection after responsing a request
 containing Content-Length and Transfer-Encoding

Closes #475
---
 .../http1/soup-server-message-io-http1.c      |  8 ++
 libsoup/soup-message-headers.c                | 88 +++++++++----------
 tests/server-test.c                           |  4 +-
 3 files changed, 52 insertions(+), 48 deletions(-)

Index: libsoup-3.4.4/libsoup/server/http1/soup-server-message-io-http1.c
===================================================================
--- libsoup-3.4.4.orig/libsoup/server/http1/soup-server-message-io-http1.c
+++ libsoup-3.4.4/libsoup/server/http1/soup-server-message-io-http1.c
@@ -653,6 +653,14 @@ parse_headers (SoupServerMessage *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_common (request_headers, SOUP_HEADER_CONTENT_LENGTH))
+                soup_message_headers_replace_common (request_headers, SOUP_HEADER_CONNECTION, "close", 1);
+
         /* Generate correct context for request */
         req_host = soup_message_headers_get_one_common (request_headers, SOUP_HEADER_HOST);
         if (req_host && strchr (req_host, '/')) {
Index: libsoup-3.4.4/libsoup/soup-message-headers.c
===================================================================
--- libsoup-3.4.4.orig/libsoup/soup-message-headers.c
+++ libsoup-3.4.4/libsoup/soup-message-headers.c
@@ -148,18 +148,6 @@ soup_message_headers_set (SoupMessageHea
 {
         switch (name) {
         case SOUP_HEADER_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;
                 break;
         case SOUP_HEADER_CONTENT_TYPE:
@@ -186,21 +174,6 @@ soup_message_headers_set (SoupMessageHea
                 } else
                         hdrs->expectations = 0;
                 break;
-        case SOUP_HEADER_TRANSFER_ENCODING:
-                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;
-                break;
         default:
                 break;
         }
@@ -947,21 +920,39 @@ soup_message_headers_foreach (SoupMessag
 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_common (hdrs, SOUP_HEADER_CONTENT_LENGTH);
-	if (header) {
-                soup_message_headers_set (hdrs, SOUP_HEADER_CONTENT_LENGTH, 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_common (hdrs, SOUP_HEADER_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_common (hdrs, SOUP_HEADER_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
@@ -971,6 +962,8 @@ soup_message_headers_get_encoding (SoupM
 	 */
 	hdrs->encoding = (hdrs->type == SOUP_MESSAGE_HEADERS_RESPONSE) ?
 		SOUP_ENCODING_EOF : SOUP_ENCODING_NONE;
+	}
+
 	return hdrs->encoding;
 }
 
openSUSE Build Service is sponsored by