headers (bsc#1254876, CVE-2025-14523, glgo#GNOME/libsoup!491). OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/libsoup2?expand=0&rev=31
126 lines
3.9 KiB
Diff
126 lines
3.9 KiB
Diff
From ff8829d85b5903d16c4b284ccc75977af20da9ba Mon Sep 17 00:00:00 2001
|
|
From: Alynx Zhou <alynx.zhou@gmail.com>
|
|
Date: Thu, 8 Jan 2026 13:05:33 +0800
|
|
Subject: [PATCH] Reject duplicate Host headers
|
|
|
|
---
|
|
libsoup/soup-headers.c | 4 +++-
|
|
libsoup/soup-message-headers-private.h | 10 ++++++++++
|
|
libsoup/soup-message-headers.c | 27 ++++++++++++++++++++------
|
|
3 files changed, 34 insertions(+), 7 deletions(-)
|
|
create mode 100644 libsoup/soup-message-headers-private.h
|
|
|
|
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c
|
|
index cc481cfa..b58f3855 100644
|
|
--- a/libsoup/soup-headers.c
|
|
+++ b/libsoup/soup-headers.c
|
|
@@ -14,6 +14,7 @@
|
|
|
|
#include "soup-headers.h"
|
|
#include "soup.h"
|
|
+#include "soup-message-headers-private.h"
|
|
|
|
/**
|
|
* soup_headers_parse:
|
|
@@ -138,7 +139,8 @@ soup_headers_parse (const char *str, int len, SoupMessageHeaders *dest)
|
|
for (p = strchr (value, '\r'); p; p = strchr (p, '\r'))
|
|
*p = ' ';
|
|
|
|
- soup_message_headers_append (dest, name, value);
|
|
+ if (!soup_message_headers_append_internal (dest, name, value))
|
|
+ goto done;
|
|
}
|
|
success = TRUE;
|
|
|
|
diff --git a/libsoup/soup-message-headers-private.h b/libsoup/soup-message-headers-private.h
|
|
new file mode 100644
|
|
index 00000000..62a4e511
|
|
--- /dev/null
|
|
+++ b/libsoup/soup-message-headers-private.h
|
|
@@ -0,0 +1,10 @@
|
|
+#ifndef __SOUP_MESSAGE_HEADERS_PRIVATE_H__
|
|
+#define __SOUP_MESSAGE_HEADERS_PRIVATE_H__ 1
|
|
+
|
|
+#include "soup-message-headers.h"
|
|
+
|
|
+gboolean
|
|
+soup_message_headers_append_internal (SoupMessageHeaders *hdrs,
|
|
+ const char *name, const char *value);
|
|
+
|
|
+#endif
|
|
diff --git a/libsoup/soup-message-headers.c b/libsoup/soup-message-headers.c
|
|
index 39ad14a0..160a52dc 100644
|
|
--- a/libsoup/soup-message-headers.c
|
|
+++ b/libsoup/soup-message-headers.c
|
|
@@ -13,6 +13,7 @@
|
|
|
|
#include "soup-message-headers.h"
|
|
#include "soup.h"
|
|
+#include "soup-message-headers-private.h"
|
|
#include "soup-misc-private.h"
|
|
|
|
/**
|
|
@@ -194,12 +195,20 @@ soup_message_headers_clean_connection_headers (SoupMessageHeaders *hdrs)
|
|
void
|
|
soup_message_headers_append (SoupMessageHeaders *hdrs,
|
|
const char *name, const char *value)
|
|
+{
|
|
+ soup_message_headers_append_internal (hdrs, name, value);
|
|
+}
|
|
+
|
|
+gboolean
|
|
+soup_message_headers_append_internal (SoupMessageHeaders *hdrs,
|
|
+ const char *name, const char *value)
|
|
{
|
|
SoupHeader header;
|
|
SoupHeaderSetter setter;
|
|
+ const char *interned_host = intern_header_name ("Host", NULL);
|
|
|
|
- g_return_if_fail (name != NULL);
|
|
- g_return_if_fail (value != NULL);
|
|
+ g_return_val_if_fail (name != NULL, FALSE);
|
|
+ g_return_val_if_fail (value != NULL, FALSE);
|
|
|
|
/* Setting a syntactically invalid header name or value is
|
|
* considered to be a programming error. However, it can also
|
|
@@ -207,26 +216,32 @@ soup_message_headers_append (SoupMessageHeaders *hdrs,
|
|
* compiled with G_DISABLE_CHECKS.
|
|
*/
|
|
#ifndef G_DISABLE_CHECKS
|
|
- g_return_if_fail (*name && strpbrk (name, " \t\r\n:") == NULL);
|
|
- g_return_if_fail (strpbrk (value, "\r\n") == NULL);
|
|
+ g_return_val_if_fail (*name && strpbrk (name, " \t\r\n:") == NULL, FALSE);
|
|
+ g_return_val_if_fail (strpbrk (value, "\r\n") == NULL, FALSE);
|
|
#else
|
|
if (*name && strpbrk (name, " \t\r\n:")) {
|
|
g_warning ("soup_message_headers_append: Ignoring bad name '%s'", name);
|
|
- return;
|
|
+ return FALSE;
|
|
}
|
|
if (strpbrk (value, "\r\n")) {
|
|
g_warning ("soup_message_headers_append: Ignoring bad value '%s'", value);
|
|
- return;
|
|
+ return FALSE;
|
|
}
|
|
#endif
|
|
|
|
header.name = intern_header_name (name, &setter);
|
|
+ if (header.name == interned_host && soup_message_headers_get_one(hdrs, "Host")) {
|
|
+ g_warning ("Attempted to add duplicate Host header to a SoupMessageHeaders that already contains a Host header");
|
|
+ return FALSE;
|
|
+ }
|
|
header.value = g_strdup (value);
|
|
g_array_append_val (hdrs->array, header);
|
|
if (hdrs->concat)
|
|
g_hash_table_remove (hdrs->concat, header.name);
|
|
if (setter)
|
|
setter (hdrs, header.value);
|
|
+
|
|
+ return TRUE;
|
|
}
|
|
|
|
/**
|
|
--
|
|
2.52.0
|
|
|