From: Vsevolod Stakhov Date: Thu, 23 Jul 2026 11:26:25 +0000 (+0100) Subject: [Fix] http: bound request bodies on controller, proxy and control sockets X-Git-Tag: 4.1.3~36 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1ae11c4db9ccb7d69c2acbd5b8aadb3e7dd5e2ea;p=thirdparty%2Frspamd.git [Fix] http: bound request bodies on controller, proxy and control sockets 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). --- diff --git a/src/controller.c b/src/controller.c index 0799151ef5..9b2081495f 100644 --- a/src/controller.c +++ b/src/controller.c @@ -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) { diff --git a/src/libserver/http/http_router.c b/src/libserver/http/http_router.c index b5255e0e46..4c03b81345 100644 --- a/src/libserver/http/http_router.c +++ b/src/libserver/http/http_router.c @@ -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); } diff --git a/src/libserver/http/http_router.h b/src/libserver/http/http_router.h index f3ce54effc..15b99b2822 100644 --- a/src/libserver/http/http_router.h +++ b/src/libserver/http/http_router.h @@ -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 diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c index 0e88701c12..cc6e92e47e 100644 --- a/src/libserver/rspamd_control.c +++ b/src/libserver/rspamd_control.c @@ -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; diff --git a/src/rspamd_proxy.c b/src/rspamd_proxy.c index 887d7e2379..d24d1bbd6e 100644 --- a/src/rspamd_proxy.c +++ b/src/rspamd_proxy.c @@ -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); }