commit e4d4f49: [Fix] Fix brain-damaged behaviour when http request has a custom Host header

Vsevolod Stakhov vsevolod at highsecure.ru
Thu Aug 12 17:21:04 UTC 2021


Author: Vsevolod Stakhov
Date: 2021-08-11 17:37:11 +0100
URL: https://github.com/rspamd/rspamd/commit/e4d4f49e87c8cd62334ab6237320a3c28f1dcb09

[Fix] Fix brain-damaged behaviour when http request has a custom Host header

---
 src/libserver/http/http_connection.c | 73 ++++++++++++++++++++++++------------
 src/libserver/http/http_connection.h |  4 ++
 src/libserver/http/http_message.c    |  5 +++
 src/lua/lua_http.c                   | 13 ++++++-
 4 files changed, 71 insertions(+), 24 deletions(-)

diff --git a/src/libserver/http/http_connection.c b/src/libserver/http/http_connection.c
index bf4d07b72..aaa34f44e 100644
--- a/src/libserver/http/http_connection.c
+++ b/src/libserver/http/http_connection.c
@@ -1871,31 +1871,58 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
 			}
 			else {
 				if (conn->priv->flags & RSPAMD_HTTP_CONN_FLAG_PROXY) {
-					rspamd_printf_fstring (buf,
-							"%s %s://%s:%d/%V HTTP/1.1\r\n"
-							"Connection: %s\r\n"
-							"Host: %s\r\n"
-							"Content-Length: %z\r\n",
-							http_method_str (msg->method),
-							(msg->flags & RSPAMD_HTTP_FLAG_SSL) ? "https" : "http",
-							host,
-							msg->port,
-							msg->url,
-							conn_type,
-							host,
-							bodylen);
+					if ((msg->flags & RSPAMD_HTTP_FLAG_HAS_HOST_HEADER)) {
+						rspamd_printf_fstring(buf,
+								"%s %s://%s:%d/%V HTTP/1.1\r\n"
+								"Connection: %s\r\n"
+								"Content-Length: %z\r\n",
+								http_method_str(msg->method),
+								(msg->flags & RSPAMD_HTTP_FLAG_SSL) ? "https" : "http",
+								msg->port,
+								msg->url,
+								conn_type,
+								host,
+								bodylen);
+					}
+					else {
+						rspamd_printf_fstring(buf,
+								"%s %s://%s:%d/%V HTTP/1.1\r\n"
+								"Connection: %s\r\n"
+								"Host: %s\r\n"
+								"Content-Length: %z\r\n",
+								http_method_str(msg->method),
+								(msg->flags & RSPAMD_HTTP_FLAG_SSL) ? "https" : "http",
+								host,
+								msg->port,
+								msg->url,
+								conn_type,
+								host,
+								bodylen);
+					}
 				}
 				else {
-					rspamd_printf_fstring (buf,
-							"%s %V HTTP/1.1\r\n"
-							"Connection: %s\r\n"
-							"Host: %s\r\n"
-							"Content-Length: %z\r\n",
-							http_method_str (msg->method),
-							msg->url,
-							conn_type,
-							host,
-							bodylen);
+					if ((msg->flags & RSPAMD_HTTP_FLAG_HAS_HOST_HEADER)) {
+						rspamd_printf_fstring(buf,
+								"%s %V HTTP/1.1\r\n"
+								"Connection: %s\r\n"
+								"Content-Length: %z\r\n",
+								http_method_str(msg->method),
+								msg->url,
+								conn_type,
+								bodylen);
+					}
+					else {
+						rspamd_printf_fstring(buf,
+								"%s %V HTTP/1.1\r\n"
+								"Connection: %s\r\n"
+								"Host: %s\r\n"
+								"Content-Length: %z\r\n",
+								http_method_str(msg->method),
+								msg->url,
+								conn_type,
+								host,
+								bodylen);
+					}
 				}
 
 				if (bodylen > 0) {
diff --git a/src/libserver/http/http_connection.h b/src/libserver/http/http_connection.h
index ada98d250..b6b199fae 100644
--- a/src/libserver/http/http_connection.h
+++ b/src/libserver/http/http_connection.h
@@ -79,6 +79,10 @@ struct rspamd_storage_shmem {
  * Do not verify server's certificate
  */
 #define RSPAMD_HTTP_FLAG_SSL_NOVERIFY (1 << 6)
+/**
+ * Body has been set for a message
+ */
+#define RSPAMD_HTTP_FLAG_HAS_HOST_HEADER (1 << 6)
 /**
  * Options for HTTP connection
  */
diff --git a/src/libserver/http/http_message.c b/src/libserver/http/http_message.c
index e68778f3e..d15856956 100644
--- a/src/libserver/http/http_message.c
+++ b/src/libserver/http/http_message.c
@@ -528,6 +528,11 @@ rspamd_http_message_add_header_len (struct rspamd_http_message *msg,
 		hdr = g_malloc0 (sizeof (struct rspamd_http_header));
 		nlen = strlen (name);
 		vlen = len;
+
+		if (g_ascii_strcasecmp (name, "host") == 0) {
+			msg->flags |= RSPAMD_HTTP_FLAG_HAS_HOST_HEADER;
+		}
+
 		hdr->combined = rspamd_fstring_sized_new (nlen + vlen + 4);
 		rspamd_printf_fstring (&hdr->combined, "%s: %*s\r\n", name, (gint)vlen,
 				value);
diff --git a/src/lua/lua_http.c b/src/lua/lua_http.c
index 3fee28583..d85664ef0 100644
--- a/src/lua/lua_http.c
+++ b/src/lua/lua_http.c
@@ -1008,9 +1008,20 @@ lua_http_request (lua_State *L)
 		cbd->item = rspamd_symcache_get_cur_item (task);
 	}
 
-	if (msg->host) {
+
+	const rspamd_ftok_t *host_header_tok = rspamd_http_message_find_header (msg, "Host");
+	if (host_header_tok != NULL) {
+		if (msg->host) {
+			g_string_free (msg->host, true);
+		}
+		msg->host = g_string_new_len (host_header_tok->begin, host_header_tok->len);
 		cbd->host = msg->host->str;
 	}
+	else {
+		if (msg->host) {
+			cbd->host = msg->host->str;
+		}
+	}
 
 	if (body) {
 		if (gzip) {


More information about the Commits mailing list