File fix-CVE-2023-46118-0.patch of Package rabbitmq-server.31584
From 0de73e5f3fef07bef8299d19faa89cc4fc01219f Mon Sep 17 00:00:00 2001
From: Michael Klishin <klishinm@vmware.com>
Date: Sat, 14 Oct 2023 06:11:01 -0400
Subject: [PATCH] Introduce HTTP request body limit for definition uploads
The default is 20 MiB, which is enough to upload
a definition file with 200K queues, a few virtual host
and a few users. In other words, it should accomodate
a lot of environments.
(cherry picked from commit b7b3514bb1f71cdad552ba712f683b4d427c4aec)
---
deps/rabbitmq_management/BUILD.bazel | 3 ++-
deps/rabbitmq_management/Makefile | 3 ++-
.../include/rabbit_mgmt.hrl | 2 ++
.../priv/schema/rabbitmq_management.schema | 17 +++++++++++++
.../src/rabbit_mgmt_util.erl | 24 ++++++++++++++-----
.../src/rabbit_mgmt_wm_definitions.erl | 11 +++++++--
6 files changed, 50 insertions(+), 10 deletions(-)
Index: rabbitmq-server-3.8.11/deps/rabbitmq_management/Makefile
===================================================================
--- rabbitmq-server-3.8.11.orig/deps/rabbitmq_management/Makefile
+++ rabbitmq-server-3.8.11/deps/rabbitmq_management/Makefile
@@ -12,7 +12,8 @@ define PROJECT_ENV
{cors_allow_origins, []},
{cors_max_age, 1800},
- {content_security_policy, "script-src 'self' 'unsafe-eval' 'unsafe-inline'; object-src 'self'"}
+ {content_security_policy, "script-src 'self' 'unsafe-eval' 'unsafe-inline'; object-src 'self'"},
+ {max_http_body_size, 20000000}
]
endef
Index: rabbitmq-server-3.8.11/deps/rabbitmq_management/include/rabbit_mgmt.hrl
===================================================================
--- rabbitmq-server-3.8.11.orig/deps/rabbitmq_management/include/rabbit_mgmt.hrl
+++ rabbitmq-server-3.8.11/deps/rabbitmq_management/include/rabbit_mgmt.hrl
@@ -8,3 +8,5 @@
-define(AUTH_REALM, "Basic realm=\"RabbitMQ Management\"").
-define(HEALTH_CHECK_FAILURE_STATUS, 503).
+
+-define(MANAGEMENT_DEFAULT_HTTP_MAX_BODY_SIZE, 20000000).
Index: rabbitmq-server-3.8.11/deps/rabbitmq_management/priv/schema/rabbitmq_management.schema
===================================================================
--- rabbitmq-server-3.8.11.orig/deps/rabbitmq_management/priv/schema/rabbitmq_management.schema
+++ rabbitmq-server-3.8.11/deps/rabbitmq_management/priv/schema/rabbitmq_management.schema
@@ -20,6 +20,23 @@
{mapping, "management.http_log_dir", "rabbitmq_management.http_log_dir",
[{datatype, string}]}.
+%% Max HTTP body limit
+
+{mapping, "management.http.max_body_size", "rabbitmq_management.max_http_body_size",
+ [{datatype, integer}, {validators, ["non_negative_integer"]}]}.
+
+{translation, "rabbitmq_management.max_http_body_size",
+fun(Conf) ->
+ case cuttlefish:conf_get("management.http.max_body_size", Conf, undefined) of
+ %% 20 MiB allows for about 200K queues across a small (single digit) number of virtual hosts with
+ %% an equally small number of users. MK.
+ undefined -> 20000000;
+ Val when is_integer(Val) -> Val;
+ Other -> cuttlefish:invalid("management.http.max_body_size must be set to a positive integer")
+ end
+end}.
+
+
%% HTTP (TCP) listener options ========================================================
%% HTTP listener consistent with Web STOMP and Web MQTT.
Index: rabbitmq-server-3.8.11/deps/rabbitmq_management/src/rabbit_mgmt_util.erl
===================================================================
--- rabbitmq-server-3.8.11.orig/deps/rabbitmq_management/src/rabbit_mgmt_util.erl
+++ rabbitmq-server-3.8.11/deps/rabbitmq_management/src/rabbit_mgmt_util.erl
@@ -782,15 +782,27 @@ id0(Key, ReqData) ->
read_complete_body(Req) ->
read_complete_body(Req, <<"">>).
-read_complete_body(Req0, Acc) ->
- case cowboy_req:read_body(Req0) of
- {ok, Data, Req} -> {ok, <<Acc/binary, Data/binary>>, Req};
- {more, Data, Req} -> read_complete_body(Req, <<Acc/binary, Data/binary>>)
+read_complete_body(Req, Acc) ->
+ BodySizeLimit = application:get_env(rabbitmq_management, max_http_body_size, ?MANAGEMENT_DEFAULT_HTTP_MAX_BODY_SIZE),
+ read_complete_body(Req, Acc, BodySizeLimit).
+read_complete_body(Req0, Acc, BodySizeLimit) ->
+ case bit_size(Acc) > BodySizeLimit of
+ true ->
+ {error, "Exceeded HTTP request body size limit"};
+ false ->
+ case cowboy_req:read_body(Req0) of
+ {ok, Data, Req} -> {ok, <<Acc/binary, Data/binary>>, Req};
+ {more, Data, Req} -> read_complete_body(Req, <<Acc/binary, Data/binary>>)
+ end
end.
with_decode(Keys, ReqData, Context, Fun) ->
- {ok, Body, ReqData1} = read_complete_body(ReqData),
- with_decode(Keys, Body, ReqData1, Context, Fun).
+ case read_complete_body(ReqData) of
+ {error, Reason} ->
+ bad_request(Reason, ReqData, Context);
+ {ok, Body, ReqData1} ->
+ with_decode(Keys, Body, ReqData1, Context, Fun)
+ end.
with_decode(Keys, Body, ReqData, Context, Fun) ->
case decode(Keys, Body) of
Index: rabbitmq-server-3.8.11/deps/rabbitmq_management/src/rabbit_mgmt_wm_definitions.erl
===================================================================
--- rabbitmq-server-3.8.11.orig/deps/rabbitmq_management/src/rabbit_mgmt_wm_definitions.erl
+++ rabbitmq-server-3.8.11/deps/rabbitmq_management/src/rabbit_mgmt_wm_definitions.erl
@@ -86,8 +86,15 @@ all_definitions(ReqData, Context) ->
Context).
accept_json(ReqData0, Context) ->
- {ok, Body, ReqData} = rabbit_mgmt_util:read_complete_body(ReqData0),
- accept(Body, ReqData, Context).
+ case rabbit_mgmt_util:read_complete_body(ReqData0) of
+ {error, Reason} ->
+ BodySizeLimit = application:get_env(rabbitmq_management, max_http_body_size, ?MANAGEMENT_DEFAULT_HTTP_MAX_BODY_SIZE),
+ _ = rabbit_log:warning("HTTP API: uploaded definition file exceeded the maximum request body limit of ~p bytes. "
+ "Use the 'management.http.max_body_size' key in rabbitmq.conf to increase the limit if necessary", [BodySizeLimit]),
+ rabbit_mgmt_util:bad_request(Reason, ReqData0, Context);
+ {ok, Body, ReqData} ->
+ accept(Body, ReqData, Context)
+ end.
vhost_definitions(ReqData, VHost, Context) ->
%% rabbit_mgmt_wm_<>:basic/1 filters by VHost if it is available