[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1004513: bullseye-pu: package rabbitmq-server/3.8.9-3



Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

I have prepared an update for rabbitmq-server/3.8.9-3
targetting Bullseye. This contains numerous adjustments. The
most important of them being the generation of the file
/var/lib/rabbitmq/.erlang.cookie which didn't have enough
entropy as per what RabbitMQ generates using Erlang. The
direct consequence, is a possible remote execution vulnerability
where the attacker simply bruteforce the value of the Erlang
cookie. As per what the default was, there's only 200 000 000
possible values (20 upper case chars, so 26 to the power of 20),
so it is estimated that in 10 minutes, someone can brutefoce
the cookie value. Using "openssl rand -base64 42", we get at
lease 2.6353924e+76 possible value which is considerably harder
to bruteforce.

Besides this, the systemd service dependency is corrected to
depend on epmd.socket instead of epmd@.socket, and there's also
an upstream patch for the rabbitmq monitoring interface (which
is less grave, IMO).

On top of this, I added a README.Debian to explain how to
correctly secure a rabbitmq-server installation. Hopefully,
this will help our users.

One thing to note: if someone was copying the older erlang
cookie to other servers part of the cluster, it *will* break
the cluster, as erlang cookies wont match. However, this is
IMO better than leaving an open RCE. Though I don't think this
will be the majority case. I expect our users running with the
wrong Erlang cookie to be running in a single node setup, and
not even knowing about the cookie entropy issue. For this case,
the upgrade will fix everything correctly and automatically.

[ Reason ]
Fixing RCE.
Fixing JS bug.
Adding doc how to secure rabbitmq.

[ Tests ]
I manually tested the new setup. The .erlang.cookie is
correctly generated, and older installation gets correctly
fixed.

[ Risks ]
Appart from the monitoring web interface of RabbitMQ, which
anyways isn't mandatory for running rabbitmq-server, all
changes are easy to audit.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

Pleasee allow me to upload rabbitmq-server/3.8.9-3+deb11u1
for the next point release.

Cheers,

Thomas Goirand (zigo)
diff --git a/debian/README.Debian b/debian/README.Debian
new file mode 100644
index 0000000..9d564c4
--- /dev/null
+++ b/debian/README.Debian
@@ -0,0 +1,134 @@
+*** WARNING ***
+
+0/ Intro
+
+RabbitMQ, in its default configuration, is insecure.  A number of
+security measures are necessary to prevent remote execution of code
+from malicious actors.
+
+
+1/ Firewalling
+
+A default RabbitMQ installation opens the following ports, with the
+following authentication schemes:
+ - 4369: EPMD daemon, for port lookups; IP-based auth limited to
+   localhost
+ - 5672: AMQP protcol; username/password auth
+ - 25672: RabbitMQ "distribution" port for inter-node communication; a
+   "magic cookie" shared secret for auth
+
+Unauthorized access to all of these ports is a security risk; you
+should configure your firewall to disallow outside access to them.
+Speifically, unrestricted access to the port 25672, with the default
+weak secret before 3.9.8-3 (see below), EXPOSES YOUR SERVER TO A
+REMOTE CODE EXECUTION VULNERABILITY.  Unrestricted access to port 4369
+serves to advertise that vulnerability.
+
+Though not open by default, RabbitMQ may also be configured to open
+the following ports, which are also strongly advised to be firewalled:
+ - 5671: AMQP with SSL
+ - 15671: Management port with SSL
+ - 15672: Management port without SSL
+
+
+2/ Erlang cookie
+
+Prior to Debian version 3.9.8-3, rabbitmq-server generated an Erlang
+"magic cookie" shared secret if one did not exist.  This secret is
+stored in /var/lib/rabbitmq/.erlang.cookie
+
+However, due to predictable seeds and a non-cryptographic randomizer,
+the automatically-generated secret written by Erlang only supplies 20
+to 40 bits of entropy.  This allows a remote attacker with access to
+port 25672 to brute-force the "magic cookie," potentially within
+minutes, authenticate as a remote node, and EXECUTE ARBITRARY CODE.
+
+Since 3.9.8-3, the rabbitmq-server node will use openssl to generate a
+cryptographically-secure cookie during first installation, mitigating
+this vulnerability.
+
+Servers which installed a prior version, and are upgrading to 3.9.8-3
+or higher, ARE STILL VULNERABLE, as the package will not regenerate
+the secret if it exists already.  This is because the secret is
+designed to be shared between nodes in a cluster, and thus
+regenerating it would break existing clusters.
+
+Operators upgrading from earlier versions of rabbitmq-server are
+strongly encouraged to generate a new secret.  This can be done via:
+
+    openssl rand -base64 42 >/var/lib/rabbitmq/.erlang.cookie
+
+
+3/ TLS
+
+It is strongly advised to use TLS to protect data in transit to your
+RabbitMQ cluster. Below is an example /etc/rabbitmq/rabbitmq.config
+which achieves that; note that it uses only RAM nodes in the cluster,
+which is not a recommended configuration for production, as it can
+lead to data loss.
+
+[
+  {rabbit, [
+    {loopback_users, [<<"guest">>]},
+    {cluster_nodes, {['rabbit@node1.example.com', 'rabbit@node2.example.com', 'rabbit@node3.example.com'], ram}},
+    {cluster_partition_handling, autoheal},
+    {tcp_listen_options, [
+         {backlog,       128},
+         {nodelay,       true},
+         {linger,        {true, 0}},
+         {exit_on_close, false}
+    ]},
+    {collect_statistics_interval, 60000},
+    {ssl_listeners, [{"10.0.1.3", 5671}]},
+    {ssl_options, [
+                   {cacertfile,"/etc/ssl/certs/my-cluster-ca-chain.pem"},
+                   {certfile,"/etc/rabbitmq/ssl/public/node1.example.com.crt"},
+                   {keyfile,"/etc/rabbitmq/ssl/private/node1.example.com.key"},
+                   {secure_renegotiate,true},
+                   {reuse_sessions,true},
+                   {honor_cipher_order,true},
+                   {verify,verify_none},
+                   {fail_if_no_peer_cert,false}
+                  ]},
+    {vm_memory_high_watermark, 0.4},
+    {default_user, <<"guest">>},
+    {default_pass, <<"guest">>}
+  ]},
+  {kernel, [
+    
+  ]}
+,
+  {rabbitmq_management, [
+    {listener, [
+      {ip, "10.0.1.3"},
+      {port, 15671},
+      {ssl, true},
+      {ssl_opts, [
+                  {cacertfile, "/etc/ssl/certs/my-cluster-ca-chain.pem"},
+                  {certfile, "/etc/rabbitmq/ssl/public/node1.example.com.crt"},
+                  {keyfile, "/etc/rabbitmq/ssl/private/node1.example.com.key"},
+                  {verify,verify_none},
+                  {fail_if_no_peer_cert,false}
+                 ]}
+    ]}
+  ]}
+].
+
+Documenting how to generate TLS certificates is out of the scope of
+this small README. However, you can see an example script to do so
+over here:
+
+https://salsa.debian.org/openstack-team/debian/openstack-cluster-installer/-/blob/debian/xena/bin/oci-root-ca-gen
+
+with the matching configuration files over here:
+
+https://salsa.debian.org/openstack-team/debian/openstack-cluster-installer/-/tree/debian/xena/etc/openstack-cluster-installer/pki
+
+
+4/ guest account
+
+The "guest" account which is pre-configured in the initial
+installation is only accessible from 127.0.0.1 or ::1; its password is
+also initially set to "guest".
+
+ -- Thomas Goirand <zigo@debian.org>  Sat, 15 Jan 2022 11:52:42 +0100
diff --git a/debian/changelog b/debian/changelog
index ab57d10..819a6b5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,33 @@
+rabbitmq-server (3.8.9-3+deb11u1) bullseye; urgency=medium
+
+  * CVE-2021-32719: In rabbitmq-server prior to version 3.8.18, when a
+    federation link was displayed in the RabbitMQ management UI via the
+    `rabbitmq_federation_management` plugin, its consumer tag was rendered
+    without proper &lt;script&gt; tag sanitization. This potentially allows
+    for JavaScript code execution in the context of the page. The user must
+    be signed in and have elevated permissions (manage federation upstreams
+    and policies) for this to occur. Applied upstream patch: Escape the
+    consumer-tag value in federation mgmt.
+  * CVE-2021-32718: In rabbitmq-server prior to version 3.8.17, a new user
+    being added via management UI could lead to the user's bane being
+    rendered in a confirmation message without proper `&lt;script&gt;` tag
+    sanitization, potentially allowing for JavaScript code execution in the
+    context of the page. In order for this to occur, the user must be signed
+    in and have elevated permissions (other user management).
+  * Closes: #990524
+  * Add a new README.Debian explaining how to secure RabbitMQ.
+  * Stop moving mv /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq-env.conf.
+  * Generate the Erlang cookie in /var/lib/rabbitmq/.erlang.cookie using
+    OpenSSL, rather than letting RabbitMQ use Erlang to generate a poor entropy
+    Erlang cookie, which was easily brute-forceable in 10 minutes. The OpenSSL
+    generated version has order of magnitudes more possible values, which makes
+    it a way harder to bruteforce. If an old Erlang cookie is detected, a new
+    one is generated, and rabbitmq-server restarted if it was running.
+  * rabbitmq-server.service now correctly depends on epmd.socket and not the
+    epmd@.socket, so it can correctly start after a reboot.
+
+ -- Thomas Goirand <zigo@debian.org>  Sat, 01 Jan 2022 18:46:04 +0100
+
 rabbitmq-server (3.8.9-3) unstable; urgency=medium
 
   [ Adam Cecile ]
diff --git a/debian/control b/debian/control
index 80f9e8b..0194a82 100644
--- a/debian/control
+++ b/debian/control
@@ -61,6 +61,7 @@ Depends:
  locales-all,
  logrotate,
  lsb-base,
+ openssl,
  socat,
  ${misc:Depends},
  ${python3:Depends},
diff --git a/debian/patches/CVE-2021-32718_Escape_username_before_displaying_it.patch b/debian/patches/CVE-2021-32718_Escape_username_before_displaying_it.patch
new file mode 100644
index 0000000..a0f4d74
--- /dev/null
+++ b/debian/patches/CVE-2021-32718_Escape_username_before_displaying_it.patch
@@ -0,0 +1,21 @@
+Description: CVE-2021-32718: Escape username before displaying it
+ All other values displayed in pop-ups are already escaped.
+Author: Michael Klishin <michael@clojurewerkz.org>
+Date: Thu, 6 May 2021 06:57:43 +0300
+Origin: upstream, https://github.com/rabbitmq/rabbitmq-server/commit/5d15ffc5ebfd9818fae488fc05d1f120ab02703c.patch
+Bug-Debian: https://bugs.debian.org/990524
+Last-Update: 2022-01-01
+
+diff --git a/deps/rabbitmq_management/priv/www/js/dispatcher.js b/deps/rabbitmq_management/priv/www/js/dispatcher.js
+index d2842c2da8a..5f1b54dbac8 100644
+--- a/deps/rabbitmq_management/priv/www/js/dispatcher.js
++++ b/deps/rabbitmq_management/priv/www/js/dispatcher.js
+@@ -189,7 +189,7 @@ dispatcher_add(function(sammy) {
+             res = sync_put(this, '/users/:username');
+             if (res) {
+                 if (res.http_status === 204) {
+-                    username = res.req_params.username;
++                    username = fmt_escape_html(res.req_params.username);
+                     show_popup('warn', "Updated an existing user: '" + username + "'");
+                 }
+                 update();
diff --git a/debian/patches/CVE-2021-32719_Escape_the_consumer-tag_value_in_federation_mgmt.patch b/debian/patches/CVE-2021-32719_Escape_the_consumer-tag_value_in_federation_mgmt.patch
new file mode 100644
index 0000000..ff8985b
--- /dev/null
+++ b/debian/patches/CVE-2021-32719_Escape_the_consumer-tag_value_in_federation_mgmt.patch
@@ -0,0 +1,21 @@
+Description: CVE-2021-32719 Escape the consumer-tag value in federation mgmt
+ Patches persistent XSS.
+Author: Patrik Ragnarsson <patrik@starkast.net>
+Date: Sat, 19 Jun 2021 09:23:12 +0200
+Origin: upstream, https://github.com/rabbitmq/rabbitmq-server/pull/3122
+Bug-Debian: https://bugs.debian.org/990524
+Last-Update: 2021-01-01
+
+diff --git a/deps/rabbitmq_federation_management/priv/www/js/tmpl/federation-upstreams.ejs b/deps/rabbitmq_federation_management/priv/www/js/tmpl/federation-upstreams.ejs
+index 5b3e14d0638..838eac1eb3b 100644
+--- a/deps/rabbitmq_federation_management/priv/www/js/tmpl/federation-upstreams.ejs
++++ b/deps/rabbitmq_federation_management/priv/www/js/tmpl/federation-upstreams.ejs
+@@ -45,7 +45,7 @@
+      <td class="r"><%= fmt_time(upstream.value['message-ttl'], 'ms') %></td>
+      <td class="r"><%= fmt_string(upstream.value['ha-policy']) %></td>
+      <td class="r"><%= fmt_string(upstream.value['queue']) %></td>
+-     <td class="r"><%= upstream.value['consumer-tag'] %></td>
++     <td class="r"><%= fmt_string(upstream.value['consumer-tag']) %></td>
+    </tr>
+ <% } %>
+  </tbody>
diff --git a/debian/patches/series b/debian/patches/series
index 75f0194..256bd33 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,4 @@
 lets-use-python3-not-python-binary.patch
 rabbitmq-dist.mk.patch
 Upstream_PR2965_fixing_rabbitmqctl_parsing
+CVE-2021-32719_Escape_the_consumer-tag_value_in_federation_mgmt.patch
diff --git a/debian/rabbitmq-server.postinst b/debian/rabbitmq-server.postinst
index efcd88e..53f8238 100644
--- a/debian/rabbitmq-server.postinst
+++ b/debian/rabbitmq-server.postinst
@@ -20,10 +20,6 @@ if [ "$1" = "configure" ] || [ "$1" = "reconfigure" ] ; then
 
 	mkdir -p /etc/rabbitmq
 	chown rabbitmq:rabbitmq /etc/rabbitmq
-	if [ -f /etc/rabbitmq/rabbitmq.conf ] && [ ! -f /etc/rabbitmq/rabbitmq-env.conf ]; then
-		mv /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq-env.conf
-		chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq-env.conf
-	fi
 	if [ -r /usr/share/rabbitmq/rabbitmq-env.conf ] && ! [ -e /etc/rabbitmq/rabbitmq-env.conf ] ; then
 		install -m 0644 -o rabbitmq -g rabbitmq /usr/share/rabbitmq/rabbitmq-env.conf /etc/rabbitmq/rabbitmq-env.conf
 	fi
@@ -35,9 +31,29 @@ if [ "$1" = "configure" ] || [ "$1" = "reconfigure" ] ; then
 	chmod 750 /var/lib/rabbitmq/mnesia
 	chmod -R o-rwx,g-w /var/lib/rabbitmq/mnesia
 
+	# We generate the erlang cookie by ourselves, just to make sure we don't
+	# leave the job to erlang that doesn't do it with enough entropy.
+	if ! [ -e /var/lib/rabbitmq/.erlang.cookie ] ; then
+		OLD_UMASK=$(umask)
+		umask 077; openssl rand -base64 -out /var/lib/rabbitmq/.erlang.cookie 42
+		umask ${OLD_UMASK}
+	else
+		# This matches an Erlang generated cookie file: 20 upper case chars
+		if grep -q -E '^[A-Z]{20}$' /var/lib/rabbitmq/.erlang.cookie ; then
+			OLD_UMASK=$(umask)
+			umask 077; openssl rand -base64 -out /var/lib/rabbitmq/.erlang.cookie 42
+			umask ${OLD_UMASK}
+			if [ ""$(ps --no-headers -o comm 1) = "systemd" ] ; then
+				if systemctl is-active --quiet rabbitmq-server.service ; then
+					systemctl restart rabbitmq-server.service
+				fi
+			fi
+		fi
+	fi
+	chmod 0400 /var/lib/rabbitmq/.erlang.cookie
+
 	chown -R rabbitmq:rabbitmq /var/lib/rabbitmq
 	chown -R rabbitmq:rabbitmq /var/log/rabbitmq
-
 fi
 
 #DEBHELPER#
diff --git a/debian/rabbitmq-server.service b/debian/rabbitmq-server.service
index 8197ae7..f3bce06 100644
--- a/debian/rabbitmq-server.service
+++ b/debian/rabbitmq-server.service
@@ -1,7 +1,7 @@
 [Unit]
 Description=RabbitMQ Messaging Server
-After=network.target epmd@.socket
-Wants=network.target epmd@.socket
+After=network.target epmd.socket
+Wants=network.target epmd.socket
 
 [Service]
 Type=notify

Reply to: