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

Bug#991321: marked as done (unblock: dovecot/1:2.3.13+dfsg1-2)



Your message dated Tue, 20 Jul 2021 21:37:17 +0000
with message-id <E1m5xQT-0008LJ-N7@respighi.debian.org>
and subject line unblock dovecot
has caused the Debian Bug report #991321,
regarding unblock: dovecot/1:2.3.13+dfsg1-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
991321: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=991321
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package dovecot

[ Reason ]

Dovecot 1:2.3.13+dfsg1-2 includes two targeted security fixes and no other
changes.  The relevant section of debian/changelog is:

dovecot (1:2.3.13+dfsg1-2) unstable; urgency=high

  * Import upstream fixes for security issues (Closes: #990566):
    - CVE-2021-29157: Path traversal issue allowing an attacker with
      access to the local filesystem can trick OAuth2 authentication into
      using an HS256 validation key from an attacker-controlled location
    - CVE-2021-33515: Sensitive information could be redirected to an
      attacker-controlled address because of a STARTTLS command injection
      bug in the submission service

 -- Noah Meyerhans <noahm@debian.org>  Tue, 20 Jul 2021 08:05:19 -0700

[ Impact ]

We release bullseye with known security issues and will likely need to fix them
in a subsequent point release.

[ Tests ]

I've done basic functionality testing.  Additionally, the fixes are backported
from upstream's changes and are already included in Ubuntu's security archive,
so they've gotten reasonable test coverage at that level.  I do not have
reproducers for the security issues, so I have been unable to verify
experimentally that the problems have been fixed.

[ Risks ]

Code changes are reasonably straightforward, and as mentioned are already
deployed elsewhere.  Further, they impact what I believe to be less common
features of dovecot, meaning that even in the worst-case scenario, impact is
likely to be limited to a small number of users.

[ 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 testing

[ Other info ]

n/a

unblock dovecot/1:2.3.13+dfsg1-2
diff -Nru dovecot-2.3.13+dfsg1/debian/changelog dovecot-2.3.13+dfsg1/debian/changelog
--- dovecot-2.3.13+dfsg1/debian/changelog	2021-01-25 23:38:17.000000000 +0000
+++ dovecot-2.3.13+dfsg1/debian/changelog	2021-07-20 15:05:19.000000000 +0000
@@ -1,3 +1,15 @@
+dovecot (1:2.3.13+dfsg1-2) unstable; urgency=high
+
+  * Import upstream fixes for security issues (Closes: #990566):
+    - CVE-2021-29157: Path traversal issue allowing an attacker with
+      access to the local filesystem can trick OAuth2 authentication into
+      using an HS256 validation key from an attacker-controlled location
+    - CVE-2021-33515: Sensitive information could be redirected to an
+      attacker-controlled address because of a STARTTLS command injection
+      bug in the submission service
+
+ -- Noah Meyerhans <noahm@debian.org>  Tue, 20 Jul 2021 08:05:19 -0700
+
 dovecot (1:2.3.13+dfsg1-1) unstable; urgency=medium
 
   [ Christian Göttsche ]
diff -Nru dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-29157.patch dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-29157.patch
--- dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-29157.patch	1970-01-01 00:00:00.000000000 +0000
+++ dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-29157.patch	2021-07-19 22:09:38.000000000 +0000
@@ -0,0 +1,134 @@
+Description: fix incorrectly escapes kid and azp fields in JWT tokens
+Origin: https://launchpadlibrarian.net/544092180/dovecot_1%3A2.3.13+dfsg1-1ubuntu1_1%3A2.3.13+dfsg1-1ubuntu1.1.diff.gz
+
+--- a/src/lib-dict-extra/dict-fs.c
++++ b/src/lib-dict-extra/dict-fs.c
+@@ -67,8 +67,37 @@ static void fs_dict_deinit(struct dict *
+ 	i_free(dict);
+ }
+ 
++/* Remove unsafe paths */
++static const char *fs_dict_escape_key(const char *key)
++{
++	const char *ptr;
++	string_t *new_key = NULL;
++	/* we take the slow path always if we see potential
++	   need for escaping */
++	while ((ptr = strstr(key, "/.")) != NULL) {
++		/* move to the first dot */
++		const char *ptr2 = ptr + 1;
++		/* find position of non-dot */
++		while (*ptr2 == '.') ptr2++;
++		if (new_key == NULL)
++			new_key = t_str_new(strlen(key));
++		str_append_data(new_key, key, ptr - key);
++		/* if ptr2 is / or end of string, escape */
++		if (*ptr2 == '/' || *ptr2 == '\0')
++			str_append(new_key, "/...");
++		else
++			str_append(new_key, "/.");
++		key = ptr + 2;
++	}
++	if (new_key == NULL)
++		return key;
++	str_append(new_key, key);
++	return str_c(new_key);
++}
++
+ static const char *fs_dict_get_full_key(struct fs_dict *dict, const char *key)
+ {
++	key = fs_dict_escape_key(key);
+ 	if (str_begins(key, DICT_PATH_SHARED))
+ 		return key + strlen(DICT_PATH_SHARED);
+ 	else if (str_begins(key, DICT_PATH_PRIVATE)) {
+--- a/src/lib-oauth2/oauth2-jwt.c
++++ b/src/lib-oauth2/oauth2-jwt.c
+@@ -250,6 +250,34 @@ oauth2_jwt_copy_fields(ARRAY_TYPE(oauth2
+ 	}
+ }
+ 
++/* Escapes '/' and '%' in identifier to %hex */
++static const char *escape_identifier(const char *identifier)
++{
++	size_t pos = strcspn(identifier, "/%");
++	/* nothing to escape */
++	if (identifier[pos] == '\0')
++		return identifier;
++
++	size_t len = strlen(identifier);
++	string_t *new_id = t_str_new(len);
++	str_append_data(new_id, identifier, pos);
++
++	for (size_t i = pos; i < len; i++) {
++	        switch (identifier[i]) {
++	        case '/':
++	                str_append(new_id, "%2f");
++	                break;
++	        case '%':
++	                str_append(new_id, "%25");
++	                break;
++	        default:
++	                str_append_c(new_id, identifier[i]);
++	                break;
++	        }
++	}
++	return str_c(new_id);
++}
++
+ static int
+ oauth2_jwt_header_process(struct json_tree *tree, const char **alg_r,
+ 			  const char **kid_r, const char **error_r)
+@@ -349,6 +377,8 @@ oauth2_jwt_body_process(const struct oau
+ 	const char *azp = get_field(tree, "azp");
+ 	if (azp == NULL)
+ 		azp = "default";
++	else
++		azp = escape_identifier(azp);
+ 
+ 	if (oauth2_validate_signature(set, azp, alg, kid, blobs, error_r) < 0)
+ 		return -1;
+@@ -401,31 +431,8 @@ int oauth2_try_parse_jwt(const struct oa
+ 	else if (*kid == '\0') {
+ 		*error_r = "'kid' field is empty";
+ 		return -1;
+-	}
+-
+-	size_t pos = strcspn(kid, "./%");
+-	if (pos < strlen(kid)) {
+-		/* sanitize kid, cannot allow dots or / in it, so we encode them */
+-		string_t *new_kid = t_str_new(strlen(kid));
+-		/* put initial data */
+-		str_append_data(new_kid, kid, pos);
+-		for (const char *c = kid+pos; *c != '\0'; c++) {
+-			switch (*c) {
+-			case '.':
+-				str_append(new_kid, "%2e");
+-				break;
+-			case '/':
+-				str_append(new_kid, "%2f");
+-				break;
+-			case '%':
+-				str_append(new_kid, "%25");
+-				break;
+-			default:
+-				str_append_c(new_kid, *c);
+-				break;
+-			}
+-		}
+-		kid = str_c(new_kid);
++	} else {
++		kid = escape_identifier(kid);
+ 	}
+ 
+ 	/* parse body */
+--- a/src/lib-oauth2/test-oauth2-jwt.c
++++ b/src/lib-oauth2/test-oauth2-jwt.c
+@@ -508,7 +508,7 @@ static void test_jwt_kid_escape(void)
+ 	 void *ptr = buffer_append_space_unsafe(secret, 32);
+ 	 random_fill(ptr, 32);
+ 	 buffer_t *b64_key = t_base64_encode(0, SIZE_MAX, secret->data, secret->used);
+-	 save_key_to("HS256", "hello%2eworld%2f%25", str_c(b64_key));
++	 save_key_to("HS256", "hello.world%2f%25", str_c(b64_key));
+ 	/* make a token */
+ 	buffer_t *tokenbuf = create_jwt_token_kid("HS256", "hello.world/%");
+ 	/* sign it */
diff -Nru dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-33515.patch dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-33515.patch
--- dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-33515.patch	1970-01-01 00:00:00.000000000 +0000
+++ dovecot-2.3.13+dfsg1/debian/patches/CVE-2021-33515.patch	2021-07-19 22:05:12.000000000 +0000
@@ -0,0 +1,62 @@
+commit 321c339756f9b2b98fb7326359d1333adebb5295
+Author: Stephan Bosch <stephan.bosch@open-xchange.com>
+Date:   Sat May 22 00:16:38 2021 +0200
+
+    lib-smtp: smtp-server-connection - Fix STARTTLS command injection vulnerability.
+    
+    The input handler kept reading more commands even though the input was locked by
+    the STARTTLS command, thereby causing it to read the command pipelined beyond
+    STARTTLS. This causes a STARTTLS command injection vulerability.
+
+--- a/src/lib-smtp/smtp-server-cmd-starttls.c
++++ b/src/lib-smtp/smtp-server-cmd-starttls.c
+@@ -37,6 +37,13 @@ static int cmd_starttls_start(struct smt
+ 		return -1;
+ 	}
+ 
++	/* The command queue must be empty at this point. If anything were to be
++	   queued somehow, this connection is vulnerable to STARTTLS command
++	   insertion.
++	 */
++	i_assert(conn->command_queue_count == 0 &&
++		 conn->command_queue_head == NULL);
++
+ 	/* RFC 3207, Section 4.2:
+ 
+ 	   Upon completion of the TLS handshake, the SMTP protocol is reset to
+@@ -107,6 +114,13 @@ cmd_starttls_next(struct smtp_server_cmd
+ 	const struct smtp_server_callbacks *callbacks = conn->callbacks;
+ 	int ret;
+ 
++	/* The command queue can only contain the STARTTLS command at this
++	   point. If anything beyond the STARTTLS were queued somehow, this
++	   connection is vulnerable to STARTTLS command insertion.
++	 */
++	i_assert(conn->command_queue_count == 1 &&
++	         conn->command_queue_tail == command);
++
+ 	smtp_server_connection_set_state(conn, SMTP_SERVER_STATE_STARTTLS,
+ 					 NULL);
+ 
+--- a/src/lib-smtp/smtp-server-connection.c
++++ b/src/lib-smtp/smtp-server-connection.c
+@@ -440,7 +440,7 @@ smtp_server_connection_handle_input(stru
+ 
+ 	/* Parse commands */
+ 	ret = 1;
+-	while (!conn->closing && ret != 0) {
++	while (!conn->closing && !conn->input_locked && ret != 0) {
+ 		while ((ret = smtp_command_parse_next(
+ 			conn->smtp_parser, &cmd_name, &cmd_params,
+ 			&error_code, &error)) > 0) {
+@@ -464,6 +464,10 @@ smtp_server_connection_handle_input(stru
+ 
+ 			if (conn->disconnected)
+ 				return;
++			/* Last command locked the input; stop trying to read
++			   more. */
++			if (conn->input_locked)
++				break;
+ 			/* Client indicated it will close after this command;
+ 			   stop trying to read more. */
+ 			if (conn->closing)
diff -Nru dovecot-2.3.13+dfsg1/debian/patches/series dovecot-2.3.13+dfsg1/debian/patches/series
--- dovecot-2.3.13+dfsg1/debian/patches/series	2021-01-25 23:38:17.000000000 +0000
+++ dovecot-2.3.13+dfsg1/debian/patches/series	2021-07-19 22:05:12.000000000 +0000
@@ -16,3 +16,5 @@
 Fix-32bit-sign-comparisons.patch
 Fix-32-bit-test-case.patch
 Improve-cross-compile-support.patch
+CVE-2021-29157.patch
+CVE-2021-33515.patch

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: