Cyrus IMAP 3.13.8 Tag Notes
Unavailable for download as this is a development branch only.
Access is via git.
Warning
This should be considered for testing purposes and bleeding-edge features only. We will try to tag these snapshots at coherent development points, but there will generally be large breaking changes occurring between releases in this series.
Major changes since the 3.12 series
Added support for the latest versions of IETF drafts:
draft-ietf-jmap-calendars
draft-ietf-calext-jscalendarbis
draft-ietf-calext-jscalendar-icalendar
draft-ietf-calext-icalendar-jscalendar-extensions
Also added a new experimental httpd module "convert" that converts between media types for selected content types. Initially it only converts between iCalendar and JSCalendar, according to the definition of the IETF draft draft-ietf-calext-jscalendar-icalendar. This module is not meant for production use and is not enabled by default.
The annotator is now called only on items added to email-type mailboxes.
ctl_conversationsdb(8) now has
-Ufor version upgrades.lmtpd(8) now provides a capability called
TRACEand a newTRACEcommand for setting an interal trace-id, which will be logged.The
admins_get_internal_seenoption has been added. If set, the admin users will always get and set the same\Seenflags as the mailbox owner.master(8)will refuse to start if multiple partitions appear to be identical or overlap. (Issue #5573:)Cyrus syslogs are in the process of being converted to
logfmt, a structured logging format. So far, this affects primarily the login logs and auditlog.The backupcyrusd(8) protocol daemon has been added to facilitate rolling backups.
The
expire_by_savedateandexpire_keep_flaggedoptions have been added to control the behavior of cyr_expire(8).Time zone data is no longer included in iTIP messages.
The IMAP PREVIEW extension will now only be advertised if the
jmap_preview_annotoption is set and begins with/shared/.Support for the IMAP
UIDBATCHESextension has been added.cyrus.conf(5) can now schedule
EVENTSwith cron-like syntax.The new
sieve_mdn_original_recipient_headeroption allows an install to get the original recipient from a header other than Original-Recipient.The new
sieve_mdn_privateoption helps prevent leaking usernames.A new database backend called
twomhas been added.Adds support for the Sieve 'vnd.cyrus.redirect-multiple' extension which allows the 'redirect' action to accept a stringlist of email addresses, in addition to the standard single string. Cyrus will use a single SMTP transaction, providing each address as a RCPT TO and stop script processing when any response is an error.
The 'sieve_extensions' option now accepts the value 'vnd.cyrus.redirect-multiple' to enable the extension in timsieved.
Cyrus now requires libical >= 4.0.0, or a current development snapshot.
Cyrus now requires libxapian >= 2.0.0, or a recent 1.5.x bleeding edge snapshot.
JMAP methods now use perfect hashes (gperf) for increased performance.
The code in
lib/imapoptionshas been refactored for easier maintenance and extensibility.Building Cyrus now requires
perl>= 5.28.0 and the modulesMooandApp::Cmd. These are usually available as OS packages - e.g. on Debian-based systems aslibmoo-perlandlibapp-cmd-perlThe mkimap(8) and rehash(8) tools are now installed to
--sbindirbymake install.Content for the documentation site (cyrusimap.org) can now be written in Markdown. Building the documentation, therefore, will now require
myst_parser, which is what makes this possible.The hash table code has been refactored to reduce memory usage and improve performance.
IMIP notifications sent to the notify socket now include the username of the authenticated user who triggered the change.
The temporary directory used by unit tests can now be set using the CYRUS_CUNIT_TMPDIR configure variable.
calalarmd now logs the scheduled-vs-actual send delay for every send it performs, via a new "auditlog.calalarmd.send.*" audit event
The
configdirectorymust now be an absolute path.The cyrus-timezones package is now part of Cyrus. The IANA time zone database is bundled, and
make installgenerates and installs the VTIMEZONEs and the time zone guessing database previously supplied by cyruslibs.zoneinfo_dirnow defaults to where they are installed. Building the time zone data needsvzic(see--with-vzic);--without-vzicbuilds none. See also the new cyr_guesstz(8).JMAP for Calendars now always uses JSCalendar 2.0, including in CalendarEventNotification objects and in iMIP notifications sent to the imipnotifier. The JSCalendar 1.0 property names are no longer accepted.
JMAP
MDN/parse(RFC 9007) is implemented, andMDN/sendnow follows RFC 9007: it requiresidentityIdandonSuccessUpdateEmail.The new
jmap_require_accountidoption makes JMAP reject method calls that omitaccountId, as RFC 8620 specifies. It is off by default, but will be on by default in some future release.JMAP
Email/queryandEmail/queryChangessupport a non-standard "category" comparator, which groups results by filter condition. It requiresjmap_nonstandard_extensions.JMAP
Email/querykeyword filters now apply to the Email as a whole, asEmail/getdoes, rather than to one of its copies.A memo (a message with the
$memokeyword) can name the message it annotates in the newX-ME-Memo-Forheader, which places it in that message's conversation.Sieve "redirect" can add a DKIM2 Message-Instance header field recording the header fields the script changed. See
dkim2_message_instance.Granting free/busy access to a calendar (JMAP
mayReadFreeBusy, or the9right) now also grants lookup, without which the grant did nothing.iTIP scheduling messages are now delivered after the request that caused them has finished with the organizer's calendar, which prevents deadlocks between an organizer and a local attendee. A scheduling CalDAV PUT therefore no longer returns an ETag.
The new
calendar_max_expanded_instancesoption limits how many instances of one recurring component a CalDAV calendar-query or a JMAPCalendarEvent/querywill expand.Non-admin users can no longer see or operate on non-email mailboxes (calendars, address books, and so on) over IMAP unless they log in with the "+dav" suffix on their userid.
JMAP and DAV now reject mailbox and collection names they cannot represent, rather than creating a mailbox with some other name, and mailbox names are now validated more strictly.
The
X-JMAP-PRIVACYiCalendar property is deprecated in favor ofCLASS.Under FUZZY search, an IMAP HEADER search of Subject, From, To, Cc or Bcc is now handled by the search engine, like the dedicated search key.
httpd can accept TLS 1.3 early data (0-RTT) if
http_allow_0rttis enabled. Early requests with unsafe methods get 425 Too Early (RFC 8470).TLS sessions can now be resumed from any service process, not only the one that issued the ticket, and servers now send close_notify. A
tls_session_timeoutof 0 now disables resumption entirely.The
zeroskipdatabase backend has been added. A zeroskip database is an append-only directory rather than a single file, and readers take no lock. See alsozeroskip_index_path.The twom database library now matches the standalone twom library. It reports a damaged database as an error rather than crashing, and a bug that made
twom_db_repaircorrupt the skiplist has been fixed.squatter(8) now records the highest createdmodseq it has indexed, preventing a race with JMAP
Email/queryChanges.The new
squatter_batch_delayoption makes squatter pause between the indexing batches of a mailbox, releasing its lock meanwhile.A graceful shutdown now waits for any write transaction in progress to finish.
reconstruct(8) now repairs JMAP mailbox id clashes.
Replication no longer deletes the wrong mailbox when a mailbox name has been reused; the replica now checks the mailbox's identity before deleting it. This requires both ends to be upgraded.
A logfmt event and key vocabulary is now documented and enforced. The few logfmt events that predated it have been renamed.
Updates to default configuration
OpenSSL version 3.0 or greater is now required for all builds.
Audit logging is now always enabled; the
auditlogoption is deprecated and has no effect.The default for
tls_eccurveis nowX25519MLKEM768:X25519:prime256v1:secp384r1, and the option now accepts a colon-separated list.HTTP support, *DAV (CalDAV, CardDAV, WebDAV) and the calendar alarm daemon are now mandatory parts of every Cyrus IMAP build. The
--enable-httpand--enable-calalarmdconfigure options have been removed; the httpd binary and calalarmd are always built. libical, libxml2 and SQLite3 are now required build dependencies.
Removed features
The undocumented
XSTATSmetrics system has been removed.The undocumented
XKILLMYcommand and its associatedSIGUSR2handler have been removed.lipcap support has been removed.
The
tls_server_dhparamoption has been deprecated.Support for the obscure "objectstore" feature has been removed.
The long deprecated
installsieveprogram has been removed. Please use sieveshell(1) instead.The legacy JMAP Contacts API has been removed (
Contact/*andContactGroup/*) - useContactCard/*instead.NNTP support has been removed: nntpd, fetchnews, remotepurge, mknewsgroups, the INN patch, and the
news2mailmailbox annotation.The RSS and CGI modules have been removed from httpd.
The fud service has been removed.
The IMAP URLAUTH extension (RFC 4467) has been removed.
Fetching calendar data as xCal (RFC 6321) is no longer supported.
CalDAV no longer supports the HTTP PATCH method (VPATCH).
CalDAV no longer supports the non-standard
application/event+jsonmedia type. Use JMAP for Calendars for JSCalendar.CalDAV no longer honors the
Schedule-Sender-AddressandSchedule-Sender-Namerequest headers.The experimental CalDAV calendar secretary mode has been removed, along with the
shareesActAsproperty of the JMAP calendar account.The experimental JMAP Admin capability (
https://cyrusimap.org/ns/jmap/admin) has been removed.The non-standard
inCalendarsfilter condition of JMAPCalendarEvent/queryhas been removed. UseinCalendar.The following options are now deprecated:
allownewnews
auditlog
caringo_hostname
caringo_port
mboxkey_db
newsaddheaders
newsgroups
newsmaster
newspeer
newspostuser
newsprefix
newsrc_db_path
nntptimeout
object_storage_dummy_spool
object_storage_enabled
openio_account
openio_autocreate
openio_namespace
openio_proxy_timeout
openio_rawx_timeout
openio_verbosity
rss_feedlist_template
rss_feeds
rss_maxage
rss_maxitems
rss_maxsynopsis
rss_realm
Security fixes
CVE-2026-47084 LOCALDELETE bypassed ACL checks
An authenticated but non-admin user could invoke the admin-only LOCALDELETE IMAP command and delete mailboxes for which they had no permissions.
Reported by: Michael Lynch (mtlynch.io)
CVE-2026-47086 GENURLAUTH issued tokens bypassing ACLs
Any authenticated user could mint a URLAUTH token (via the GENURLAUTH command) for any mailbox they could name, even without read access on it. This would allow reading mail from mailboxes despite having no granted permissions.
Reported by: Matthew Horsfall
CVE-2026-47087 URLAUTH does not honor revoked authorizer access
A URLAUTH URL minted while the authorizer had access continued to work after that access was revoked.
Reported by: Matthew Horsfall
CVE-2026-47081 XAPPLEPUSHSERVICE folder existence oracle and push hijack
An authenticated IMAP user could probe for the existence of arbitrary mailboxes on other users' accounts via the XAPPLEPUSHSERVICE command and then create Apple Push Notification Service notifications for new mail in those mailboxes to their own APNS device. This did not leak any data about the content of mailboxes. Instead, a "mailbox has changed" notice would be pushed when the mailbox modseq changed.
Reported by Matthew Horsfall.
CVE-2026-47089 LISTRIGHTS not limited to users with admin access
An authenticated user could call IMAP LISTRIGHTS against any mailbox they could name and learn what principals had what access to it. (This action should have been restricted to users with admin access on the target mailbox.)
Reported by: Matthew Horsfall
CVE-2026-47085 URLAUTH token forgery via missing mboxkey
If an attacker knew a folder name on the victim's account for which the victim had never issued an auth URL, they could forge a working URLAUTH token by computing HMAC-SHA1 with a predictable key, allowing them read access to the mailbox.
URLAUTH is an obscure feature, meaning that the odds of any user actually being susceptible to this attack are very low. We are unaware of any clients using URLAUTH.
Reported by: Matthew Horsfall
CVE-2026-47083 ESEARCH cross-user content oracle
Using the ESEARCH command, an authenticated IMAP user could enumerate folder names under any account they could name. Search would return UIDs of messages matching search, creating a content oracle without allowing arbitrary reads of the target's content.
Reported by: Michael Lynch (mtlynch.io)
CVE-2026-47088 Heap exposure in nested MIME comment parsing
An authenticated IMAP user could specially craft an email containing an RFC 822 comment ending with a backslash. When parsing the message, the server would read past the message end in memory and read into the heap, returning the read content to the user.
Reported by: Michael Lynch (mtlynch.io).
CVE-2026-47082 Vacation "fcc" skips destination-mailbox ACL
A user whose vacation Sieve script used :fcc (to save a copy of the sent message) could deliver vacation auto-reply copies into any mailbox the script could name, regardless of whether the script owner had insert permissions on the destination mailbox.
Reported by: Michael Lynch (mtlynch.io)
CVE-2026-61906 SMTP command injection via JMAP EmailSubmission/set envelope
An authenticated JMAP user could smuggle SMTP commands into Cyrus's internal connection to the backend SMTP server by including CRLF in envelope parameters, and so pass arbitrary commands to the local SMTP server.
Reported by: Michael Lynch (mtlynch.io).
CVE-2026-61907 JMAP snooze bypasses destination-mailbox ACL
An authenticated user with insert permissions on another user's snoozed mailbox could cause insertion of mail to that user's inbox, or any other of their mailboxes whose id was known to the user, despite having no insert permissions to the target mailbox.
Reported by: Michael Lynch (mtlynch.io).
CVE-2026-61908 JMAP email-header blob ID out-of-bounds index
An authenticated user could attempt to download a specially crafted JMAP blob ID of the form
H<emailid>-<index>, which could read past the end of the internal blob_headers array during download, exposing adjacent heap memory.Reported by: Ahmed Said.
CVE-2026-61909 CalDAV/CardDAV multiget bypasses per-href ACL
An authenticated DAV user with some shared access to another user's calendar or address book could read even unshared events or contacts by including the target hrefs in a calendar-multiget or addressbook-multiget REPORT.
Reported by: Ahmed Said.
CVE-2026-61910 Mailbox/set let sharee change special-use role on shared mailboxes
An authenticated user with maySetKeywords on another user's mailbox could change that mailbox's specialuse annotation. This could allow the sharee to change the shared mailbox to perform the archived, snoozed, or other role, which might cause mail to be written to the shared mailbox, sharing more content than intended.
This is likely to be an unusual situation, made more unusual because if the target already has a non-shared mailbox with that role, role duplication suppression will prevent the update.
Reported by: Michael Lynch (mtlynch.io).
CVE-2026-61911 Sieve mailbox existence oracle
An authenticated user could install a Sieve script that probed whether another user's private mailbox existed, or read the value of shared mailbox annotations, by observing which fileinto branch fired during LMTP delivery.
Reported by: Michael Lynch (mtlynch.io).
CVE-2026-61915 VPATCH BYPARAM double-free
An authenticated calendar user could crash a Cyrus CalDAV worker with a PATCH containing
PATCH-ACTION="BYPARAM@..."against a resource with two or more properties of the matched kind. The memory holding the selector would be freed once on each iteration over the properties.Reported by: Michael Lynch (mtlynch.io).
The following security fixes were made in public, without an embargo, as described in How we classify security issues.
Deeply nested message/rfc822 parts no longer overflow the stack in the MIME parser; parsing stops descending at
boundary_limit.Revoking a sharee's DAV access to a calendar or address book now also drops their subscription to it, and calalarmd no longer sends alarms to a sharee whose access has been revoked.
IMAP CATENATE now counts TEXT and UTF8 parts toward
maxmessagesize, which could previously be exceeded.JMAP
Email/copybetween accounts and the saved copy made byEmailSubmission/setare now charged against the storage quota.The list form of IMAP GETMETADATA now performs the same ACL checks as the single-mailbox form, and no longer reveals whether a mailbox exists.
IMAP LIST ... RETURN (STATUS) now returns STATUS only for mailboxes the user can read, and LIST (SUBSCRIBED) reports a subscribed mailbox the user can no longer look up as \NonExistent.
IMAP THREAD now reads at most 20 references from any one message.
Fixed a buffer overflow when appending DEPTH to a long metadata entry name.
xtext escapes in an LMTP
AUTH=parameter now decode correctly, rather than truncating the identity used for ACL checks.The number of parameters accepted from one MIME header is now capped at 128.
HTTP/2 request bodies are now bounded by
maxmessagesize.WebSocket messages are now bounded in size, both as received and after permessage-deflate inflation.
Malformed or out-of-range HTTP chunk sizes are now rejected, rather than truncated so that a chunk could be read as the start of another request.
A malformed DAV If: header no longer crashes httpd.
httpd now escapes the client-supplied Host header in HTML responses, preventing reflected cross-site scripting.
Negative numeric Sieve match variable references are now rejected.
A dlist parsed from stored metadata can no longer contain a file literal, which previously wrote a file to disk.
JMAP vCard blobIds now encode the content identifier of the card, so they cannot be constructed and do not resolve to replaced content. Older blobIds are rejected.
JMAP
CalendarEvent/participantReplynow requires the event's organizer to be one of the calendar owner's addresses, and sharees acting for the owner needmayWriteAll.A calendar's display name is now properly escaped in a Content-Disposition header, and httpd drops any response header containing control characters.
JMAP
accountIdandfromAccountIdarguments are now validated before being used to build paths.Setting
isSeenSharedwith JMAPMailbox/setnow requires the admin right.MANAGED-ID parameters are now stripped from ATTACH properties in iMIP messages, so a sender can no longer cause another event's managed attachment to be expunged.
JMAP
Backup/restoreCalendarsnow stores each user's private per-user data under that user, rather than all of it under the restored account.The iSchedule receiver now requires the Originator header to match the ORGANIZER (or, for a REPLY, an ATTENDEE) of the message.
CalDAV and CardDAV DELETE and MOVE now require both the
tanderights.A calendar sharee without
mayWriteAllormayWriteOwncan no longer change an event's SEQUENCE.An iMIP REPLY from an attendee not on the stored event no longer adds that attendee to it.
Recurrence expansion is now bounded by
calendar_max_expanded_instances.
Significant bugfixes
lmtpd(8) will no longer reset the session id after
LHLO.implicit_owner_rightsare now respected on HTTP-based protocols, like JMAP.Zero-byte attachments are no longer sent to the attachment text extractor, which rejected them and logged an IOERROR for each one.
A batched squatter(8) update now resumes where its previous batch stopped, so a non-incremental Xapian run no longer re-indexes the first batch of a large mailbox forever. It also restarts from the beginning of a mailbox that was deleted and recreated between batches.
IMAP SEARCH now handles non-ASCII search terms when the client has enabled UTF8=ACCEPT or IMAP4rev2 rather than passing a CHARSET.
JMAP
Email/queryChangesnow treats thesnoozedUntilandaddedDatessorts as mutable, reports the right index for an email with a copy in another mailbox, and reports every moved email of a thread when sorting bysomeInThreadHaveKeyword.A PROPFIND on a URI that maps to no resource now returns 404, rather than a 207 wrapping a 404. (Issue #5667)
Fixed a crash in CalDAV free/busy lookups covering several recipients when one of them publishes a CALDAV:calendar-availability.
ctl_zoneinfo(8)
-rnow indexes a time zone alias in a region directory under its full name (Indian/Mayotte, notMayotte).promstatsd(8) is less susceptible to timing drift.
Deleting a user no longer removes another user's per-user databases and search indexes. Previously this could happen after a user had been renamed, because those files are keyed by the INBOX uniqueid.
Replication now converges the quota modseq, usergroup memberships and the reverse-ACL modseq, which previously could stay out of step indefinitely.
A replica can now lose a base conversation id that the master no longer has, instead of failing replication of that mailbox on every run.
sync_client -unow repairs a user the replica has lost, even when the replication cache says the user is in sync.