commit 00927e0: [Fix] Fix host header usage in lua_http

Vsevolod Stakhov vsevolod at highsecure.ru
Sat Jan 29 13:49:04 UTC 2022


Author: Vsevolod Stakhov
Date: 2022-01-29 13:44:50 +0000
URL: https://github.com/rspamd/rspamd/commit/00927e0ef03a05916151c15c16f7e2697d655379 (HEAD -> master)

[Fix] Fix host header usage in lua_http
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 |  6 +++++-
 src/libserver/http/http_message.h |  4 +++-
 src/lua/lua_http.c                | 22 +++++++++++++++++-----
 3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/libserver/http/http_message.c b/src/libserver/http/http_message.c
index a313283f3..23ff85cd7 100644
--- a/src/libserver/http/http_message.c
+++ b/src/libserver/http/http_message.c
@@ -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;
 		}
 	}
diff --git a/src/libserver/http/http_message.h b/src/libserver/http/http_message.h
index 1750c1dd6..38f599048 100644
--- a/src/libserver/http/http_message.h
+++ b/src/libserver/http/http_message.h
@@ -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
 }
diff --git a/src/lua/lua_http.c b/src/lua/lua_http.c
index ce2a48d63..0ff8695d3 100644
--- a/src/lua/lua_http.c
+++ b/src/lua/lua_http.c
@@ -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 */


More information about the Commits mailing list