Hi,
On Stalwart 0.16.24, an unauthenticated session on port 25 can use any address of a domain hosted by the server as its envelope sender (MAIL FROM), even from a host that the domain’s own SPF record does not authorise (SPF ending in -all). With the default spfFromVerify (relaxed), the SPF failure only adds to the spam score, as documented, so the message is accepted:
- delivered to a local mailbox when its spam score stays under the threshold, where it looks like internal mail;
- expanded to the external members of a local mailing list. That copy leaves from the server’s own IP, which the domain’s SPF authorises, so the external provider would see SPF pass and, with an aligned From and a published DMARC record, DMARC pass for a forged message.
For the server’s own domains, requiring SPF pass seems a natural safeguard: a legitimate sender of a local domain either authenticates or sends from a host its SPF record lists. As far as I can tell, today this is only possible with a custom Sieve script. spfFromVerify doesn’t seem able to express it, since it is evaluated when the connection opens and accepts connection variables only (crates/registry/src/schema/structs_impl.rs L35745-35757, allowed_variables: MTA_CONNECTION_VARIABLE; evaluated from crates/smtp/src/inbound/spawn.rs L74), so it cannot depend on sender_domain. Setting it to strict applies to every domain, which also refuses legitimately forwarded mail.
It would be very useful to have a configuration-only way to require SPF pass for unauthenticated messages whose MAIL FROM domain is hosted locally, while keeping the configured SPF policy for other domains. Perhaps by evaluating spfFromVerify after MAIL FROM with the sender variables available, or through a dedicated setting for local domains. Since such a check can also reject legitimate forwarding that keeps the original envelope sender, even with a valid DKIM signature, it probably fits best as something administrators enable deliberately.
To reproduce:
- Local domain example.com with SPF “v=spf1 ip4: -all”, DMARC “v=DMARC1; p=none”, a mailbox [email protected] and a mailing list [email protected] with one external member.
- From an address not listed in that SPF record, unauthenticated on port 25: MAIL FROM:[email protected], RCPT TO:[email protected], DATA with From: [email protected].
- The message is accepted and queued for the external member, to be sent from the server’s own IP.
- With RCPT TO:[email protected], it is accepted for local delivery; whether it reaches the Inbox depends on its spam score.
Thanks for considering it!