Package: release.debian.org Severity: normal Tags: trixie X-Debbugs-Cc: [email protected] Control: affects -1 + src:cyrus-imapd User: [email protected] Usertags: pu
[ Reason ] 9 open CVE issues in trixie that are fixed in testing. [ Impact ] Users are vulnerable to the security issues. [ Tests ] I (sponsor) have only build-tested this on amd64. The submitter may have done additional tests and I have asked him to submit additional details. [ Risks ] (Discussion of the risks involved. E.g. code is trivial or complex, alternatives available.) [ 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 stable [x] the issue is verified as fixed in unstable [ Changes ] This includes the upstream patches from the stable 3.10 tree that are marked to fix the CVEs and apply cleanly on the trixie version.
diff -Nru cyrus-imapd-3.10.2/debian/changelog cyrus-imapd-3.10.2/debian/changelog --- cyrus-imapd-3.10.2/debian/changelog 2026-07-12 21:29:05.000000000 +0200 +++ cyrus-imapd-3.10.2/debian/changelog 2026-07-27 23:12:24.000000000 +0200 @@ -1,3 +1,11 @@ +cyrus-imapd (3.10.2-1+deb13u2) trixie; urgency=medium + + * Add CVE fixes from upstream branch/version 3.10.3: CVE-2026-47084, + CVE-2026-47086, CVE-2026-47087, CVE-2026-47081, CVE-2026-47089, + CVE-2026-47085, CVE-2026-47083, CVE-2026-47088, CVE-2026-47082. + + -- Codin <[email protected]> Mon, 27 Jul 2026 14:12:24 -0700 + cyrus-imapd (3.10.2-1+deb13u1) trixie; urgency=medium * http_jmap: allow JMAP EventSource without WebSocket/wslay; backport diff -Nru cyrus-imapd-3.10.2/debian/patches/0020-lmtp_sieve.c-enforce-ACL-on-vacation-fcc-destination.patch cyrus-imapd-3.10.2/debian/patches/0020-lmtp_sieve.c-enforce-ACL-on-vacation-fcc-destination.patch --- cyrus-imapd-3.10.2/debian/patches/0020-lmtp_sieve.c-enforce-ACL-on-vacation-fcc-destination.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0020-lmtp_sieve.c-enforce-ACL-on-vacation-fcc-destination.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,100 @@ +From db6d646d001c396dd1406db74eb4b98c081e15ed Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Thu, 23 Apr 2026 08:31:14 +1000 +Subject: [PATCH] lmtp_sieve.c: enforce ACL on vacation :fcc destination + +Enforce *some* ACL check when delivering the fcc for a vacation message! +Rather than pass aclcheck=0, pass ACL_INSERT: the script owner must be +able to write to the target mailbox. + +This is CYR-2892, CVE-2026-47082. + +This problem was reported by Michael Lynch (mtlynch.io). + +Co-authored-by: Claude <[email protected]> +--- + .../Sieve/vacation_with_fcc_otheruser_denied | 58 +++++++++++++++++++ + imap/lmtp_sieve.c | 2 +- + 2 files changed, 59 insertions(+), 1 deletion(-) + create mode 100644 cassandane/tiny-tests/Sieve/vacation_with_fcc_otheruser_denied + +diff --git a/cassandane/tiny-tests/Sieve/vacation_with_fcc_otheruser_denied b/cassandane/tiny-tests/Sieve/vacation_with_fcc_otheruser_denied +new file mode 100644 +index 000000000..ed9ff9a92 +--- /dev/null ++++ b/cassandane/tiny-tests/Sieve/vacation_with_fcc_otheruser_denied +@@ -0,0 +1,58 @@ ++#!perl ++use Cassandane::Tiny; ++ ++sub test_vacation_with_fcc_otheruser_denied ++ :min_version_3_1 ++ :NoAltNameSpace ++ :want_smtpdaemon ++{ ++ my ($self) = @_; ++ ++ my $target = "user.other.target"; ++ ++ xlog $self, "Create victim user 'other' and a target folder"; ++ $self->{instance}->create_user('other'); ++ ++ my $admintalk = $self->{adminstore}->get_client(); ++ $admintalk->create($target) ++ or die "Cannot create $target: $@"; ++ ++ xlog $self, "Give cassandane read-only access (no 'i'/'p' rights)"; ++ $admintalk->setacl($target, 'cassandane' => 'lrs'); ++ $self->assert_str_equals('ok', ++ $admintalk->get_last_completion_response()); ++ ++ xlog $self, "Confirm cassandane cannot APPEND directly to $target"; ++ my $talk = $self->{store}->get_client(); ++ $talk->append($target, ++ "From: nobody\@example.com\r\n" ++ . "Subject: direct-append\r\n\r\n" ++ . "denied\r\n"); ++ $self->assert_str_equals('no', ++ $talk->get_last_completion_response()); ++ ++ xlog $self, "Install a vacation rule that :fcc's into the victim's folder"; ++ $self->{instance}->install_sieve_script(<<EOF ++require ["vacation", "fcc"]; ++ ++vacation :fcc "$target" :days 1 :addresses ["cassandane\@example.com"] text: ++I am out of the office today. I will answer your email as soon as I can. ++. ++; ++EOF ++ ); ++ ++ xlog $self, "Deliver a message to trigger the vacation auto-reply"; ++ my $msg1 = $self->{gen}->generate( ++ subject => "Message 1", ++ to => Cassandane::Address->new(localpart => 'cassandane', ++ domain => 'example.com'), ++ ); ++ $self->{instance}->deliver($msg1); ++ ++ xlog $self, "Check that nothing was filed into the victim's folder"; ++ $admintalk->select($target); ++ $self->assert_str_equals('ok', ++ $admintalk->get_last_completion_response()); ++ $self->assert_num_equals(0, $admintalk->get_response_code('exists')); ++} +diff --git a/imap/lmtp_sieve.c b/imap/lmtp_sieve.c +index f13a26629..b85bf1ad2 100644 +--- a/imap/lmtp_sieve.c ++++ b/imap/lmtp_sieve.c +@@ -1931,7 +1931,7 @@ static void do_fcc(script_data_t *sdata, sieve_fileinto_context_t *fcc, + } + if (!r) { + r = append_setup(&as, intname, userid, sdata->authstate, +- 0, NULL, NULL, 0, EVENT_MESSAGE_APPEND); ++ ACL_INSERT, NULL, NULL, 0, EVENT_MESSAGE_APPEND); + } + if (!r) { + struct stagemsg *stage; +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0021-imap-message.c-fix-heap-exposure-in-nested-MIME-comm.patch cyrus-imapd-3.10.2/debian/patches/0021-imap-message.c-fix-heap-exposure-in-nested-MIME-comm.patch --- cyrus-imapd-3.10.2/debian/patches/0021-imap-message.c-fix-heap-exposure-in-nested-MIME-comm.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0021-imap-message.c-fix-heap-exposure-in-nested-MIME-comm.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,147 @@ +From 23495997b52a1ffdbc8b655d803f0b58167e40d6 Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Wed, 22 Apr 2026 15:55:30 +1000 +Subject: [PATCH] imap/message.c: fix heap exposure in nested MIME comment + parsing + +Fix out-of-bounds read in message_parse_rfc822space() when parsing RFC +822 comments that end with backslash. The backslash case would increment +p past a NUL terminator, and the subsequent loop increment would read +into adjacent heap memory. + +Add bounds check after backslash handling to prevent reading past the +end of the buffer. + +This is CYR-2882, CVE-2026-47088. + +This problem was reported by Michael Lynch (mtlynch.io). + +Co-Authored-By: Claude <[email protected]> +--- + cassandane/Cassandane/Cyrus/MIME.pm | 40 +++++++++++++++ + cassandane/tiny-tests/MIME/nested_comment_oob | 50 +++++++++++++++++++ + imap/message.c | 4 ++ + 3 files changed, 94 insertions(+) + create mode 100644 cassandane/Cassandane/Cyrus/MIME.pm + create mode 100644 cassandane/tiny-tests/MIME/nested_comment_oob + +diff --git a/cassandane/Cassandane/Cyrus/MIME.pm b/cassandane/Cassandane/Cyrus/MIME.pm +new file mode 100644 +index 000000000..58df5a251 +--- /dev/null ++++ b/cassandane/Cassandane/Cyrus/MIME.pm +@@ -0,0 +1,40 @@ ++# SPDX-License-Identifier: BSD-3-Clause-CMU ++# See COPYING file at the root of the distribution for more details. ++ ++package Cassandane::Cyrus::MIME; ++use strict; ++use warnings; ++use Data::Dumper; ++ ++use base qw(Cassandane::Cyrus::TestCase); ++use Cassandane::Util::Log; ++ ++sub new ++{ ++ my ($class, @args) = @_; ++ ++ my $config = Cassandane::Config->default()->clone(); ++ ++ my $self = $class->SUPER::new({ ++ config => $config, ++ services => [ 'imap' ] ++ }, @args); ++ ++ return $self; ++} ++ ++sub set_up ++{ ++ my ($self) = @_; ++ $self->SUPER::set_up(); ++} ++ ++sub tear_down ++{ ++ my ($self) = @_; ++ $self->SUPER::tear_down(); ++} ++ ++use Cassandane::Tiny::Loader 'tiny-tests/MIME'; ++ ++1; +diff --git a/cassandane/tiny-tests/MIME/nested_comment_oob b/cassandane/tiny-tests/MIME/nested_comment_oob +new file mode 100644 +index 000000000..b47f6b1b3 +--- /dev/null ++++ b/cassandane/tiny-tests/MIME/nested_comment_oob +@@ -0,0 +1,50 @@ ++#!perl ++use Cassandane::Tiny; ++ ++sub test_nested_comment_oob ++{ ++ my ($self) = @_; ++ ++ my $talk = $self->{store}->get_client(); ++ ++ # Create a multipart message where the vulnerability is in a nested part. ++ # Based on the PoC description, this reproduces the backslash handling bug ++ # in message_parse_rfc822space() when parsing nested Content-Type headers. ++ # The malformed header must be the last content to ensure backslash is final byte. ++ my $msg = <<'EOF'; ++From: [email protected] ++To: [email protected] ++Subject: Test heap disclosure ++Content-Type: multipart/mixed; boundary="BOUNDARY" ++ ++--BOUNDARY ++Content-Type: text/plain ++ ++This is a normal part. ++ ++--BOUNDARY ++Content-Type: text/plain (\ ++EOF ++ ++ # Remove trailing newline so backslash is the final byte before NUL ++ chomp $msg; ++ $msg =~ s/\r?\n/\r\n/gs; ++ ++ # Append the message ++ $talk->append('INBOX', $msg) || die $@; ++ ++ # Select the mailbox ++ $talk->select('INBOX'); ++ $self->assert_str_equals('ok', $talk->get_last_completion_response()); ++ ++ # Fetch BODYSTRUCTURE - this exercises the vulnerable MIME parsing code ++ # In vulnerable versions, this may crash or leak heap data as MIME parameters ++ my $response = $talk->fetch('1', 'BODYSTRUCTURE'); ++ $self->assert_str_equals('ok', $talk->get_last_completion_response()); ++ ++ # Log the bodystructure for manual inspection of any anomalies ++ # In a release build with heap spray, unexpected parameters may appear ++ if ($response && $response->{1} && $response->{1}->{bodystructure}) { ++ xlog $self, "BODYSTRUCTURE: " . Data::Dumper::Dumper($response->{1}->{bodystructure}); ++ } ++} +diff --git a/imap/message.c b/imap/message.c +index a5b633e19..f18b1c6f6 100644 +--- a/imap/message.c ++++ b/imap/message.c +@@ -1768,6 +1768,10 @@ static void message_parse_rfc822space(const char **s) + + case '\\': + p++; ++ if (*p == '\0') { ++ *s = 0; /* backslash at end of string */ ++ return; ++ } + break; + + case '(': +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0022-imapd-MULTISEARCH-must-check-ACL_READ-on-each-mailbo.patch cyrus-imapd-3.10.2/debian/patches/0022-imapd-MULTISEARCH-must-check-ACL_READ-on-each-mailbo.patch --- cyrus-imapd-3.10.2/debian/patches/0022-imapd-MULTISEARCH-must-check-ACL_READ-on-each-mailbo.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0022-imapd-MULTISEARCH-must-check-ACL_READ-on-each-mailbo.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,94 @@ +From 0534c4e30a4a09e9b8d606bf8f0e874152e8f294 Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Wed, 22 Apr 2026 08:51:29 +1000 +Subject: [PATCH] imapd: MULTISEARCH must check ACL_READ on each mailbox + +multisearch_cb opened caller-supplied mailboxes from +MAILBOXES/SUBTREE/SUBTREE-ONE and ran index_search on them without +checking whether the caller could read the mailbox. SELECT has the +equivalent gate (imapd.c:5001); MULTISEARCH did not. + +The effect is a cross-user read oracle: SUBTREE on another user's +account returns one `* ESEARCH ... MAILBOX "..."` line per folder +(folder enumeration for free), and BODY/SUBJECT predicates then probe +the contents one search at a time. An attacker only needs to be able +to name a target mailbox. + +This is CYR-2881, CVE-2026-47083. + +This problem was reported by Michael Lynch (mtlynch.io). + +Co-Authored-By: Claude <[email protected]> +--- + cassandane/Cassandane/Cyrus/Search.pm | 40 +++++++++++++++++++++++++++ + imap/imapd.c | 5 ++++ + 2 files changed, 45 insertions(+) + +diff --git a/cassandane/Cassandane/Cyrus/Search.pm b/cassandane/Cassandane/Cyrus/Search.pm +index 19e16fab7..d9e5e9e1e 100644 +--- a/cassandane/Cassandane/Cyrus/Search.pm ++++ b/cassandane/Cassandane/Cyrus/Search.pm +@@ -757,4 +757,44 @@ sub test_uidsearch_empty + $self->assert_str_equals('0', $results[0][3]); + } + ++sub test_multisearch_cross_user ++ :NoAltNamespace ++{ ++ my ($self) = @_; ++ ++ my $admintalk = $self->{adminstore}->get_client; ++ my $talk = $self->{store}->get_client; ++ ++ # victim has a private subfolder with a message. cassandane has no ++ # explicit grant on it, only whatever the "anyone p" default provides -- ++ # i.e. ACL_POST, which is not enough to run a search. ++ $self->{instance}->create_user('victim'); ++ ++ $admintalk->create('user.victim.private') ++ || die "create: " . $admintalk->get_last_error; ++ ++ $admintalk->append( ++ 'user.victim.private', ++ "From: t\@example.com\r\nSubject: secret\r\n\r\nconfidential body", ++ ) || die "append: " . $admintalk->get_last_error; ++ ++ # Check our assumptions: default user has no access to victim's private ++ # folder. ++ $talk->select('user.victim.private'); ++ $self->assert_str_equals('no', $talk->get_last_completion_response); ++ ++ # The actual test: assert that cassandane user can't find anything by ++ # ESEARCHing victim's private mailbox. ++ my @esearch_responses; ++ $talk->_imap_cmd( ++ 'ESEARCH', 0, ++ { esearch => sub { push @esearch_responses, $_[1] } }, ++ 'IN', '(MAILBOXES "user.victim.private")', ++ 'RETURN', '(ALL)', 'ALL', ++ ); ++ ++ $self->assert_str_equals('ok', $talk->get_last_completion_response); ++ $self->assert_deep_equals([], \@esearch_responses); ++} ++ + 1; +diff --git a/imap/imapd.c b/imap/imapd.c +index f48b63911..89963ebe9 100644 +--- a/imap/imapd.c ++++ b/imap/imapd.c +@@ -6080,6 +6080,11 @@ static int multisearch_cb(const mbentry_t *mbentry, void *rock) + hash_lookup(mbentry->name, &mrock->mailboxes)) + return 0; + ++ /* Skip mailboxes the caller can't read. */ ++ if (!imapd_userisadmin && ++ !(cyrus_acl_myrights(imapd_authstate, mbentry->acl) & ACL_READ)) ++ return 0; ++ + switch (mrock->filter) { + case SEARCH_SOURCE_INBOXES: + /* Only allow user's INBOX or those postable by anonymous */ +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0023-imapd-reject-URLFETCH-when-no-mboxkey-exists-for-the.patch cyrus-imapd-3.10.2/debian/patches/0023-imapd-reject-URLFETCH-when-no-mboxkey-exists-for-the.patch --- cyrus-imapd-3.10.2/debian/patches/0023-imapd-reject-URLFETCH-when-no-mboxkey-exists-for-the.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0023-imapd-reject-URLFETCH-when-no-mboxkey-exists-for-the.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,44 @@ +From 1d39d32c3b6a61241651763855b336122686fd7e Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Tue, 21 Apr 2026 08:16:10 +1000 +Subject: [PATCH] imapd: reject URLFETCH when no mboxkey exists for the mailbox + +Instead of treating "there's no mboxkey.db entry for this folder" as +indicating a zero-length key, treat a missing mboxkey entry as a +validation failure. + +(Also close the mboxkey db on the previously-unclosed error paths.) + +This is CYR-2876, CVE-2026-47085. + +This problem reported by Matthew Horsfall. + +Co-Authored-By: Claude <[email protected]> +--- + imap/imapd.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/imap/imapd.c b/imap/imapd.c +index 460c6aac6..f48b63911 100644 +--- a/imap/imapd.c ++++ b/imap/imapd.c +@@ -14076,7 +14076,15 @@ static void cmd_urlfetch(char *tag) + if (r) break; + + r = mboxkey_read(mboxkey_db, intname, &key, &keylen); +- if (r) break; ++ if (!r && (!key || !keylen)) { ++ /* If there's no key, we can't possibly validate against ++ * it! */ ++ r = IMAP_BADURL; ++ } ++ if (r) { ++ mboxkey_close(mboxkey_db); ++ break; ++ } + + HMAC(EVP_sha1(), key, keylen, (unsigned char *) arg.s, + url.urlauth.rump_len, vtoken, &vtoken_len); +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0024-imapd-LISTRIGHTS-requires-admin-rights.patch cyrus-imapd-3.10.2/debian/patches/0024-imapd-LISTRIGHTS-requires-admin-rights.patch --- cyrus-imapd-3.10.2/debian/patches/0024-imapd-LISTRIGHTS-requires-admin-rights.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0024-imapd-LISTRIGHTS-requires-admin-rights.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,43 @@ +From 5c97794e5270b472130af4531f290812cbcc6879 Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Tue, 21 Apr 2026 08:28:15 +1000 +Subject: [PATCH] imapd: LISTRIGHTS requires admin rights + +cmd_listrights was refusing only when the caller had *no* rights at +all on the target mailbox, when it should've been requiring admin +rights. + +With this patch, we'll properly require ACL_ADMIN (owners and admins +still pass through), matching the check cmd_getacl already uses. When +the caller has ACL_LOOKUP but not ACL_ADMIN, return PERMISSION_DENIED; +otherwise hide the mailbox as NONEXISTENT. + +This is CYR-2872, CVE-2026-47089. + +This problem reported by Matthew Horsfall. + +Co-Authored-By: Claude <[email protected]> +--- + imap/imapd.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/imap/imapd.c b/imap/imapd.c +index eacd6cedd..460c6aac6 100644 +--- a/imap/imapd.c ++++ b/imap/imapd.c +@@ -8530,9 +8530,10 @@ static void cmd_listrights(char *tag, char *name, char *identifier) + if (!r) { + rights = cyrus_acl_myrights(imapd_authstate, mbentry->acl); + +- if (!rights && !imapd_userisadmin && ++ if (!(rights & ACL_ADMIN) && !imapd_userisadmin && + !mboxname_userownsmailbox(imapd_userid, intname)) { +- r = IMAP_MAILBOX_NONEXISTENT; ++ r = (rights & ACL_LOOKUP) ? ++ IMAP_PERMISSION_DENIED : IMAP_MAILBOX_NONEXISTENT; + } + } + +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0025-imapd-require-read-access-for-XAPPLEPUSHSERVICE-mail.patch cyrus-imapd-3.10.2/debian/patches/0025-imapd-require-read-access-for-XAPPLEPUSHSERVICE-mail.patch --- cyrus-imapd-3.10.2/debian/patches/0025-imapd-require-read-access-for-XAPPLEPUSHSERVICE-mail.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0025-imapd-require-read-access-for-XAPPLEPUSHSERVICE-mail.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,37 @@ +From 50f77bad3048e7050ad0cd448615d9643463c16d Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Tue, 21 Apr 2026 09:05:40 +1000 +Subject: [PATCH] imapd: require read access for XAPPLEPUSHSERVICE mailboxes + +Only accept a mailbox if the caller is its owner, an admin, or holds +ACL_READ. Anything else is silently skipped (no echo, no event), which +also preserves the existing "missing" behaviour for non-existent names. + +This is CYR-2871, CVE-2026-47081. + +This problem reported by Matthew Horsfall. + +Co-Authored-By: Claude <[email protected]> +--- + imap/imapd.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/imap/imapd.c b/imap/imapd.c +index fba38ed2c..eacd6cedd 100644 +--- a/imap/imapd.c ++++ b/imap/imapd.c +@@ -14820,7 +14820,10 @@ static void cmd_xapplepushservice(const char *tag, + char *intname = + mboxname_from_external(name, &imapd_namespace, imapd_userid); + r = mlookup(tag, name, intname, &mbentry); +- if (!r && mbtype_isa(mbentry->mbtype) == MBTYPE_EMAIL) { ++ if (!r && mbtype_isa(mbentry->mbtype) == MBTYPE_EMAIL && ++ (imapd_userisadmin || ++ mboxname_userownsmailbox(imapd_userid, intname) || ++ (cyrus_acl_myrights(imapd_authstate, mbentry->acl) & ACL_READ))) { + strarray_push(¬if_mailboxes, name); + if (applepushserviceargs->aps_version >= 2) { + prot_puts(imapd_out, "* XAPPLEPUSHSERVICE \"mailbox\" "); +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0026-imapd.c-re-check-URLAUTH-authorizer-access-just-in-t.patch cyrus-imapd-3.10.2/debian/patches/0026-imapd.c-re-check-URLAUTH-authorizer-access-just-in-t.patch --- cyrus-imapd-3.10.2/debian/patches/0026-imapd.c-re-check-URLAUTH-authorizer-access-just-in-t.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0026-imapd.c-re-check-URLAUTH-authorizer-access-just-in-t.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,52 @@ +From 8380d0fb3d74b5c3a0a198db24ba4d8835781587 Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Wed, 29 Apr 2026 08:38:25 +1000 +Subject: [PATCH] imapd.c: re-check URLAUTH authorizer access just in time + +cmd_urlfetch validated the HMAC token against the authorizer's mboxkey, +but skipped any ACL check whenever url.urlauth.access was set. Sure, +the rights existed right at that moment, but if access is revoked after +the URL is created, the URL needs to stop working. We need to just +check access JIT. + +This is CYR-2868, CVE-2026-47087. + +Co-Authored-By: Claude <[email protected]> +--- + imap/imapd.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/imap/imapd.c b/imap/imapd.c +index 3392dc622..fba38ed2c 100644 +--- a/imap/imapd.c ++++ b/imap/imapd.c +@@ -14113,6 +14113,26 @@ static void cmd_urlfetch(char *tag) + } + if (r) goto err; + ++ /* For URLAUTH-protected URLs, re-check the authorizer's ACL. The ++ * HMAC asserts that authorization DID exist, but may have since been ++ * revoked. We can't read the ACL via state->mailbox here: when the ++ * URL targets the currently-selected mailbox we reuse imapd_index, ++ * whose mailbox handle is closed between commands. */ ++ if (url.urlauth.access) { ++ mbentry_t *authz_mbentry = NULL; ++ r = mlookup(NULL, NULL, intname, &authz_mbentry); ++ if (!r) { ++ struct auth_state *authzstate = auth_newstate(url.user); ++ int authz_rights = ++ cyrus_acl_myrights(authzstate, authz_mbentry->acl); ++ auth_freestate(authzstate); ++ if (!(authz_rights & ACL_READ)) ++ r = IMAP_BADURL; ++ } ++ mboxlist_entry_free(&authz_mbentry); ++ if (r) goto err; ++ } ++ + if (url.uidvalidity && + (state->mailbox->i.uidvalidity != url.uidvalidity)) { + r = IMAP_BADURL; +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0027-imapd-require-read-access-on-mailbox-in-GENURLAUTH.patch cyrus-imapd-3.10.2/debian/patches/0027-imapd-require-read-access-on-mailbox-in-GENURLAUTH.patch --- cyrus-imapd-3.10.2/debian/patches/0027-imapd-require-read-access-on-mailbox-in-GENURLAUTH.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0027-imapd-require-read-access-on-mailbox-in-GENURLAUTH.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,45 @@ +From e7a28ccf9bddd64db45542ea4a109d8060eb6f6d Mon Sep 17 00:00:00 2001 +From: Ricardo Signes <[email protected]> +Date: Tue, 21 Apr 2026 07:57:26 +1000 +Subject: [PATCH] imapd: require read access on mailbox in GENURLAUTH + +You can't grant access to things you can't access! Without this check, +any authenticated user could mint a URLAUTH token for any mailbox they +could name, because cmd_urlfetch skipped the ACL check whenever +urlauth.access is set -- it trusts that the presence of a valid HMAC +means the authorizing user was entitled to delegate. + +Require the authorizer to have at least ACL_READ on the mailbox before +issuing a token. + +This is CYR-2868, CVE-2026-47086. + +This problem reported by Matthew Horsfall. + +Co-Authored-By: Claude <[email protected]> +--- + imap/imapd.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/imap/imapd.c b/imap/imapd.c +index dfe782f8f..3392dc622 100644 +--- a/imap/imapd.c ++++ b/imap/imapd.c +@@ -14250,6 +14250,14 @@ static void cmd_genurlauth(char *tag) + continue; + } + ++ /* You can't give permission you don't have! */ ++ if (!imapd_userisadmin && ++ !(cyrus_acl_myrights(imapd_authstate, mbentry->acl) & ACL_READ)) { ++ mboxlist_entry_free(&mbentry); ++ r = IMAP_BADURL; ++ goto err; ++ } ++ + mboxlist_entry_free(&mbentry); + + /* lookup key */ +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/0028-imapd-fix-cmd_delete-force-handling.patch cyrus-imapd-3.10.2/debian/patches/0028-imapd-fix-cmd_delete-force-handling.patch --- cyrus-imapd-3.10.2/debian/patches/0028-imapd-fix-cmd_delete-force-handling.patch 1970-01-01 01:00:00.000000000 +0100 +++ cyrus-imapd-3.10.2/debian/patches/0028-imapd-fix-cmd_delete-force-handling.patch 2026-07-27 23:12:24.000000000 +0200 @@ -0,0 +1,54 @@ +From 304255f5be82cbe9c0b7db7f4dba6b16381da2ec Mon Sep 17 00:00:00 2001 +From: ellie timoney <[email protected]> +Date: Fri, 17 Apr 2026 11:55:05 +1000 +Subject: [PATCH] imapd: fix cmd_delete 'force' handling + +mboxlist_deletemailbox expects to be told whether this is a forced +action by the MBOXLIST_DELETE_FORCE flag, but this was not being +plumbed through. Forced actions are supposed to require isadmin +permission, but with the flag not set correctly, that check was +being skipped. + +As a side effect, a non-admin user could invoke the admin-only +"localdelete" command and delete mailboxes they shouldn't have +rights to. + +This is CYR-2867, CVE-2026-47084. + +This problem was reported by Michael Lynch (mtlynch.io). +--- + imap/imapd.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/imap/imapd.c b/imap/imapd.c +index 65ce5c053..dfe782f8f 100644 +--- a/imap/imapd.c ++++ b/imap/imapd.c +@@ -7350,19 +7350,22 @@ static void cmd_delete(char *tag, char *name, int localonly, int force) + /* local mailbox */ + if (!r) { + int isadmin = imapd_userisadmin || imapd_userisproxyadmin; ++ int delflags = force ? MBOXLIST_DELETE_FORCE : 0; + + if (mbname_isdeleted(mbname)) { + r = mboxlist_deletemailbox(mbname_intname(mbname), + isadmin, imapd_userid, + imapd_authstate, mboxevent, +- MBOXLIST_DELETE_LOCALONLY); ++ delflags | MBOXLIST_DELETE_LOCALONLY); + } + else if (!isadmin && mbname_issystem(mbname)) { + r = IMAP_PERMISSION_DENIED; + } + else { + delete_user = mboxname_isusermailbox(mbname_intname(mbname), 1); +- int delflags = (1-force) ? MBOXLIST_DELETE_CHECKACL : 0; ++ ++ if (!force) ++ delflags |= MBOXLIST_DELETE_CHECKACL; + + if (!delete_user && mboxlist_haschildren(mbname_intname(mbname))) { + r = IMAP_MAILBOX_HASCHILDREN; +-- +2.47.3 + diff -Nru cyrus-imapd-3.10.2/debian/patches/series cyrus-imapd-3.10.2/debian/patches/series --- cyrus-imapd-3.10.2/debian/patches/series 2026-07-12 21:29:05.000000000 +0200 +++ cyrus-imapd-3.10.2/debian/patches/series 2026-07-27 23:12:24.000000000 +0200 @@ -7,4 +7,13 @@ 0012-Use-UnicodeData.txt-from-system.patch 0018-increase-test-timeout.patch #0019-propagate-XXFLAGS.patch +0020-lmtp_sieve.c-enforce-ACL-on-vacation-fcc-destination.patch +0021-imap-message.c-fix-heap-exposure-in-nested-MIME-comm.patch +0022-imapd-MULTISEARCH-must-check-ACL_READ-on-each-mailbo.patch +0023-imapd-reject-URLFETCH-when-no-mboxkey-exists-for-the.patch +0025-imapd-require-read-access-for-XAPPLEPUSHSERVICE-mail.patch +0026-imapd.c-re-check-URLAUTH-authorizer-access-just-in-t.patch +0027-imapd-require-read-access-on-mailbox-in-GENURLAUTH.patch +0028-imapd-fix-cmd_delete-force-handling.patch +0024-imapd-LISTRIGHTS-requires-admin-rights.patch eventsource-without-websocket.patch

