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