]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Fix host header usage in lua_http
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 29 Jan 2022 13:44:50 +0000 (13:44 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 29 Jan 2022 13:44:50 +0000 (13:44 +0000)
The issue is that `rspamd_http_message_get_http_host` actually returns
non zero-terminated string in the case where `Host` header is found in a
message. Hence, we *cannot* treat it as a zero terminated string.

The proper approach is to use `rspamd_ftok_t` everywhere for strings
but the change will be too intrusive, since it also involves many libraries,
e.g. `rdns` and others.

The current approach is much simplier: just copy a string into a temporary
buffer ensuring that it is zero terminated in all the cases.

Issue: #4051

src/libserver/http/http_message.c
src/libserver/http/http_message.h
src/lua/lua_http.c

index a313283f36f6ef68090671929492276cda9f3abf..23ff85cd74c83fc0cfb02e01e4729a186afd3ead 100644 (file)
@@ -693,7 +693,8 @@ rspamd_http_message_remove_header (struct rspamd_http_message *msg,
 }
 
 const gchar*
-rspamd_http_message_get_http_host (struct rspamd_http_message *msg)
+rspamd_http_message_get_http_host (struct rspamd_http_message *msg,
+                                                                  gsize *hostlen)
 {
        if (msg->flags & RSPAMD_HTTP_FLAG_HAS_HOST_HEADER) {
                rspamd_ftok_t srch;
@@ -703,14 +704,17 @@ rspamd_http_message_get_http_host (struct rspamd_http_message *msg)
                khiter_t k = kh_get (rspamd_http_headers_hash, msg->headers, &srch);
 
                if (k != kh_end (msg->headers)) {
+                       *hostlen = (kh_value (msg->headers, k)->value).len;
                        return (kh_value (msg->headers, k)->value).begin;
                }
                else if (msg->host) {
+                       *hostlen = msg->host->len;
                        return msg->host->str;
                }
        }
        else {
                if (msg->host) {
+                       *hostlen = msg->host->len;
                        return msg->host->str;
                }
        }
index 1750c1dd6fb6a471376c75dd00f870ce8435d63f..38f59904863e97be8ec2e70f770cdebbfefa5d7c 100644 (file)
@@ -233,9 +233,11 @@ guint rspamd_http_message_get_flags (struct rspamd_http_message *msg);
  * Returns an HTTP hostname for a message, derived from a header if it has it
  * or from a url if it doesn't
  * @param msg
+ * @param hostlen output of the host length
  * @return
  */
-const gchar* rspamd_http_message_get_http_host (struct rspamd_http_message *msg);
+const gchar* rspamd_http_message_get_http_host (struct rspamd_http_message *msg,
+               gsize *hostlen);
 
 #ifdef  __cplusplus
 }
index ce2a48d631aa9c662631291d26faefff33bc5416..0ff8695d31eba1fa6ce96db384b76f07a1cb4f66 100644 (file)
@@ -75,7 +75,7 @@ struct lua_http_cbdata {
        struct rspamd_cryptobox_pubkey *peer_pk;
        rspamd_inet_addr_t *addr;
        gchar *mime_type;
-       const gchar *host;
+       gchar *host;
        gchar *auth;
        const gchar *url;
        gsize max_size;
@@ -134,6 +134,10 @@ lua_http_fin (gpointer arg)
                g_free (cbd->auth);
        }
 
+       if (cbd->host) {
+               g_free (cbd->host);
+       }
+
        if (cbd->local_kp) {
                rspamd_keypair_unref (cbd->local_kp);
        }
@@ -1060,13 +1064,18 @@ lua_http_request (lua_State *L)
        bool numeric_ip = false;
 
        /* Check if we can skip resolving */
-       cbd->host = rspamd_http_message_get_http_host (msg);
+       gsize hostlen = 0;
+       const gchar *host = rspamd_http_message_get_http_host (msg, &hostlen);
+
+       if (host) {
+               cbd->host = malloc (hostlen + 1);
+               rspamd_strlcpy (cbd->host, host, hostlen + 1);
 
-       if (cbd->host) {
                if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_KEEP_ALIVE) {
                        const rspamd_inet_addr_t *ka_addr = rspamd_http_context_has_keepalive(NULL,
-                                       rspamd_http_message_get_http_host (msg),
-                                       msg->port, msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL);
+                                       cbd->host,
+                                       msg->port,
+                                       msg->flags & RSPAMD_HTTP_FLAG_WANT_SSL);
 
                        if (ka_addr) {
                                cbd->addr = rspamd_inet_address_copy(ka_addr);
@@ -1083,6 +1092,9 @@ lua_http_request (lua_State *L)
                        }
                }
        }
+       else {
+               cbd->host = NULL;
+       }
 
        if (numeric_ip) {
                /* Host is numeric IP, no need to resolve */