From e4d4f49e87c8cd62334ab6237320a3c28f1dcb09 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Wed, 11 Aug 2021 17:37:11 +0100 Subject: [PATCH] [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) { -- 2.39.5