Cerb (11.1.9) is a maintenance update released on May 13, 2026. It includes 11 minor features and fixes from community feedback covering the 11.1 update. You can follow these instructions to upgrade.

Changelog

Changed

  • [Records/Logs/Mailboxes] Mailbox creation is now recorded in the activity log.

  • [Profiles/Widgets] Added support for manually specifying a ticket ID in the 'Ticket Conversation' profile widget, with fallback to auto-detection for tickets, drafts, and messages.

  • [Profiles/Tickets] Added the Cc: header to forwarded messages when replying to tickets.

  • [Mail/UX] Included Bcc: headers in outgoing email headers for SMTP and null mail transports.

  • [Worklists/UX] Improved row selection behavior with text selection handling in worklists. It's now possible to select and copy text again.

Fixed

  • [Records/Roles/UX] Workers without the comment create permission on a record type no longer see the 'Comment' button on profile pages. [#1020]

  • [Workflows/Builder] Fixed an issue in the workflow builder where a KATA parse error (e.g. having both version: and version@date: as sibling keys) silently produced an empty workflow template. [#1873]

Security

  • [Security] Hardened the random number generator used for security-sensitive secrets. CerberusApplication::generatePassword() and _DevblocksMultiFactorAuthService::generateMultiFactorOtpSeed() now use random_int() (CSPRNG-backed) instead of mt_rand() + str_shuffle(). This affects the session CSRF token, password recovery codes, worker invitation codes, support center contact recovery/captcha codes/password salts, and TOTP/MFA shared secrets.

  • [Security] Equalized response timing on the worker login form to mitigate user enumeration. Previously, when the submitted email didn't match a worker, the request short-circuited before any bcrypt work — letting an attacker time the response to learn whether an email is registered. The "no such worker" branch now runs password_verify($password, $dummy_hash) against a precomputed PASSWORD_DEFAULT bcrypt hash before redirecting, so the response time matches the "wrong password" path. The hash's plaintext is random and discarded, so the verify always returns false. Empty email/password still fails fast (not an enumeration vector).

  • [Security] Replaced the legacy == password-hash comparison in DAO_Worker::login() with hash_equals(). The modern (method=1) path already uses constant-time password_verify(); this closes the last byte-by-byte string compare on the legacy SHA1(salt+MD5) path that pre-9.4 worker auth hashes use until they auto-upgrade on next successful login.

  • [Security] Improved validation in the Support Center history view.