github foxcpp/maddy v0.9.7
[SECURITY] maddy 0.9.7

4 hours ago

Summary

This release includes fixes for several reported security
vulnerabilities with CVSS severity ranging Low to High, including
two DMARC verification bypasses. Upgrade is highly recommended.

This release fixes several long-standing issues in go-imap-sql
implementation. Upgrading is highly recommended for anyone using
IMAP implementation. Fixes are fully compatible with 0.9.6 -
messages written by 0.9.7 are readable by 0.9.6 as-is and vice versa.

Now storage.imapsql can store malformed MIME messages. Such messages are
stored as a single-part application/octet-stream message. This can cause
display issues with most IMAP clients but no data is lost.

Security

  • dmarc: Fix DMARC bypass when the From domain uses mixed case
    (GHSA-qh5c-2mrx-4ppj,
    no CVE assigned yet).

Messages whose From domain contained uppercase characters could be checked
against the wrong organizational domain, so the domain’s published DMARC policy
was not applied. An attacker could spoof a domain that publishes p=reject or
p=quarantine and get the message delivered.

Affects configurations using inbound SMTP with dmarc yes (default).

  • dmarc: Reject messages without a single valid author domain when DMARC is
    enabled
    (GHSA-fhw2-mvqf-h69c,
    not CVE assigned yet) (#879).

Messages with a malformed or multiple-address From header were treated as
having no DMARC policy and accepted, allowing an attacker to bypass DMARC by
deliberately breaking the From header. The new dmarc_reject_invalid_from
option controls this behavior; it is enabled in the new default configuration,
while existing deployments must enable it explicitly.

Affects configurations using inbound SMTP with dmarc yes (default).

Unknown usernames previously caused fewer LDAP operations than existing
usernames, allowing unauthenticated clients to enumerate valid accounts through
timing differences. This can aid targeted phishing and credential-stuffing
attacks.

Affects all configurations using auth.ldap.

  • proxy_protocol: Trust only the configured host for bare IPv6 addresses
    (GHSA-58jf-c377-6r8w;
    no CVE assigned yet) (#884).

A bare IPv6 address in the proxy_protocol trust list was treated as a /32
network, trusting unrelated IPv6 peers in the same range. A directly connected
attacker could forge PROXY headers to choose the client IP seen by SMTP/IMAP,
bypassing rate limits and DNSBL checks and falsifying audit logs.

Affects configurations using proxy_protocol on a public-facing endpoints (not
recommended in general).

  • limits: Fix a panic when source rate limits are exhausted without IP limits
    (GHSA-wcj3-m6rw-7gv9;
    no CVE assigned yet).

With a source limit but no ip limit, exhausting the source bucket set made
the cleanup path dereference a nil IP limiter. A remote sender could trigger a
nil-pointer panic, disrupting message acceptance on the affected SMTP endpoint.

Bug fixes

  • endpoint/smtp: Replace an invalid Date header with a valid value instead of
    rejecting the message during submission preparation (#518).
  • endpoint/smtp: Recognize wrapped SMTP errors so oversized messages are
    reported as "message too large" instead of "internal server error" (#772).
  • endpoint/smtp: Only clean up session state after a successful commit and
    abort failed deliveries, preventing stuck deliveries and spurious "database
    is locked" errors (#786).
  • endpoint/smtp: Fix a shutdown race that could deadlock the server when a
    client connected while the endpoint was stopping.
  • endpoint/smtp: Export the maddy_smtp_failed_logins metric and count failed
    AUTH attempts for every SASL mechanism (#868).
  • smtpconn: Treat wrapped dial errors as temporary network errors, so an
    unavailable LMTP server produces a retryable 450 response instead of a
    permanent 554 (#872) (PR #874, thanks @amlaban65).
  • storage/imapsql: Fix APPENDLIMIT reporting: STATUS now returns the
    effective per-mailbox limit, the capability is advertised without a value,
    and disabling the limit is rejected instead of making clients see a zero
    limit incorrectly (#788).
  • storage/imapsql: Avoid holding a DB write transaction for the whole
    delivery and clean up staged messages on failure, reducing “database is
    locked” errors with concurrent deliveries and reroute (#786).
  • storage/imapsql: Treat interrupted deliveries and serialization failures as
    temporary errors so the sender retries instead of the message being lost.
  • storage/imapsql: Fix SEARCH UNSEEN returning flags from other mailboxes and
    missing unseen messages, and fix delivery ignoring the \Seen flag set by
    IMAP filters (#591).
  • storage/imapsql: Fix compound SEARCH queries with multiple excluded flags,
    which caused fetchmail to re-download already seen messages (#703).
  • storage/imapsql: Report messages without Content-Transfer-Encoding as 7BIT
    in BODYSTRUCTURE instead of an invalid NIL value, fixing display in some IMAP
    clients (#756).
  • storage/imapsql: Accept and store messages with malformed MIME structure
    instead of failing delivery (#466).
  • storage/imapsql: Reject attempts to move a mailbox into itself.
  • storage/imapsql: Fix a missing transaction commit that left message flags,
    such as read/unread state, stale (#712).
  • target/queue: Fix truncated exponential retry delays so queued mail follows
    the documented 5min × 1.25^(n−1) schedule (#678).
  • target/queue: Reduce default initial_retry_time to 5m from 15m, add missing
    documentation for delay configuration (#678).
  • target/remote: Fix a panic when checking MTA-STS policies for
    internationalized (IDNA) domains.
  • modify/replace_addr: Apply relative aliases even when the exact address
    lookup returns the address unchanged (#734) (PR #871, thanks @mvanhorn).
  • log: Make maddy version and the server startup log report the same version,
    including custom builds (#869) (PR #870, thanks @MFAshby).
  • auth/dovecot_sasl, endpoint/dovecot_sasld: Fix user ID parsing, formatting
    and escaping in the Dovecot authentication protocol; the auth server now
    passes the authenticated user ID back to Dovecot.
  • libdns/hetzner: Update to the new Hetzner DNS API; the old API no longer
    works (#807).

Improvements

  • dns: Reload /etc/resolv.conf when it changes (checked at most every five
    seconds), so DNS changes from network reconfiguration take effect without
    restarting maddy (#475).
  • target/remote: Log MX/TLS policy decisions at normal log level, including
    policy names, effective security levels and rejection reasons, making
    outbound delivery issues easier to diagnose (#717).
  • libdns: Update DNS provider integrations to libdns 1.1 and their latest
    releases; leaseweb and gandi use forks upgraded to libdns 1.1, outdates
    deprecation warnings were removed.
  • Dockerfile: Add bash to the image so the command system filter can be
    used in container deployments (PR #851, thanks @terminar).

Documentation

  • tls: Clarify the actual default TLS versions and cipher suites, their
    dependence on the Go version, and how to re-enable legacy ciphers for older
    servers (#702, #789).
  • maddy.conf: Point new users to an example aliases file for the (aliases)
    file table syntax (#684) (PR #729, thanks @stellarpower).

Misc

  • table: Fix data races in file table reload tests.
  • tests: Add a fetchmail interoperability integration test.
  • lint: Clean up linter findings in auth/pam, endpoint/dovecot_sasld,
    endpoint/imap and queue tests.

Don't miss a new maddy release

NewReleases is sending notifications on new releases.