]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Fix brain-damaged behaviour when http request has a custom Host header
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 11 Aug 2021 16:37:11 +0000 (17:37 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 11 Aug 2021 16:37:11 +0000 (17:37 +0100)
src/libserver/http/http_connection.c
src/libserver/http/http_connection.h
src/libserver/http/http_message.c
src/lua/lua_http.c

index bf4d07b72ac78e362a0d80ade964545957803a61..aaa34f44eaa4e61170aa8930fa90bdb6bec6ed57 100644 (file)
@@ -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) {
index ada98d2503ce46735ba9b842b52703f8b07c94fe..b6b199fae5e173c1dea66a831e5bc7b09fd73958 100644 (file)
@@ -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
  */
index e68778f3e08d2e2a8ee3e3fd76b235151a68f921..d1585695667b9f10ce2dabe41ac56a6b475a23b9 100644 (file)
@@ -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);
index 3fee285833ae3d007a5ed70e116fddb3e6dcb571..d85664ef08c4da008e416a2cf849d23b1e04b3c0 100644 (file)
@@ -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) {