]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] http: bound request bodies on controller, proxy and control sockets
authorVsevolod Stakhov <vsevolod@rspamd.com>
Thu, 23 Jul 2026 11:26:25 +0000 (12:26 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Thu, 23 Jul 2026 11:26:25 +0000 (12:26 +0100)
The normal worker caps HTTP bodies at cfg->max_message, but the
controller router, the proxy client connection and the main control
socket never called rspamd_http_connection_set_max_size. A declared
Content-Length caused an unbounded preallocation and chunked input
could grow until the connection ended, all before routing or
authentication.

Add a max_size knob to the HTTP router applied to every accepted
connection, and set cfg->max_message as the body cap on the
controller, proxy and control sockets. Oversized requests are now
rejected with 413 (controller) or a closed connection (proxy).

src/controller.c
src/libserver/http/http_router.c
src/libserver/http/http_router.h
src/libserver/rspamd_control.c
src/rspamd_proxy.c

index 0799151ef504f57c7f7b1693c46150957f5d9609..9b2081495f9042ecabe757a7e2acd8ce9d4b039d 100644 (file)
@@ -4171,6 +4171,7 @@ start_controller_worker(struct rspamd_worker *worker)
        ctx->http = rspamd_http_router_new(rspamd_controller_error_handler,
                                                                           rspamd_controller_finish_handler, ctx->timeout,
                                                                           ctx->static_files_dir, ctx->http_ctx);
+       rspamd_http_router_set_max_size(ctx->http, ctx->cfg->max_message);
 
        if (rspamd_worker_has_ssl_socket(worker)) {
                if (ctx->ssl_cert && ctx->ssl_key) {
index b5255e0e46a66287553c94a91a6105a675a0b38c..4c03b81345e78822d2f8ba838080779c0adfc508 100644 (file)
@@ -523,6 +523,13 @@ void rspamd_http_router_set_ssl(struct rspamd_http_connection_router *router,
        router->server_ssl_ctx = ssl_ctx;
 }
 
+void rspamd_http_router_set_max_size(struct rspamd_http_connection_router *router,
+                                                                        gsize sz)
+{
+       g_assert(router != NULL);
+       router->max_size = sz;
+}
+
 void rspamd_http_router_handle_socket_ssl(struct rspamd_http_connection_router *router,
                                                                                  int fd, gpointer ud, gboolean ssl)
 {
@@ -540,6 +547,8 @@ void rspamd_http_router_handle_socket_ssl(struct rspamd_http_connection_router *
                                                                                                   rspamd_http_router_finish_handler,
                                                                                                   0);
 
+       rspamd_http_connection_set_max_size(conn->conn, router->max_size);
+
        if (router->key) {
                rspamd_http_connection_set_key(conn->conn, router->key);
        }
index f3ce54effc79ce6b8bb9ac5daebc9a1febd34c27..15b99b28225c0bb6a58d2845b1b36102b300bad8 100644 (file)
@@ -60,6 +60,7 @@ struct rspamd_http_connection_router {
        rspamd_http_router_error_handler_t error_handler;
        rspamd_http_router_finish_handler_t finish_handler;
        gpointer server_ssl_ctx;
+       gsize max_size;
 };
 
 /**
@@ -135,6 +136,15 @@ void rspamd_http_router_add_regexp(struct rspamd_http_connection_router *router,
 void rspamd_http_router_set_ssl(struct rspamd_http_connection_router *router,
                                                                gpointer ssl_ctx);
 
+/**
+ * Set the maximum size of a request body accepted by the router
+ * (0 means no limit)
+ * @param router router object
+ * @param sz maximum body size in bytes
+ */
+void rspamd_http_router_set_max_size(struct rspamd_http_connection_router *router,
+                                                                        gsize sz);
+
 /**
  * Handle new accepted socket
  * @param router router object
index 0e88701c128d89e19a2ed89ebc98f754412499fc..cc6e92e47eabcc9087d489cdb149c123f1e98905 100644 (file)
@@ -788,6 +788,9 @@ void rspamd_control_process_client_socket(struct rspamd_main *rspamd_main,
                                                                                                          rspamd_control_error_handler,
                                                                                                          rspamd_control_finish_handler,
                                                                                                          0);
+       /* Control commands are URL based, so the body is not used at all */
+       rspamd_http_connection_set_max_size(session->conn,
+                                                                               rspamd_main->cfg->max_message);
        session->rspamd_main = rspamd_main;
        session->addr = addr;
        session->event_loop = rspamd_main->event_loop;
index 887d7e237904e673826c0d669c4ca35616ebbd09..d24d1bbd6ead7c0fa13aeff2603122d028830347 100644 (file)
@@ -3364,6 +3364,9 @@ proxy_accept_socket(EV_P_ ev_io *w, int revents)
                        proxy_client_finish_handler,
                        http_opts);
 
+               rspamd_http_connection_set_max_size(session->client_conn,
+                                                                                       ctx->cfg->max_message);
+
                if (ctx->key) {
                        rspamd_http_connection_set_key(session->client_conn, ctx->key);
                }