milter: the level-2 domain limit is the login's domain's (audit M1)
Security audit 2026-10-17, finding M1, stage 1. overLimit took domainOf(MAIL FROM) whatever the login, and MailFrom ran it with an empty login: with smtpd_delay_reject at its default Postfix runs no sender restriction at MAIL and sends the milter's MAIL event at once, so a stranger on 465/587 with no AUTH, or another tenant's application, could name a victim domain in MAIL FROM and take its slots for the 10-minute in-flight TTL, get the victim's application answered 451, and have a limit row (and the "a rate limit is refusing mail" notification) written under the victim's domain. Now overLimit returns at once without a login and takes the domain from ApplicationByLogin (loginDomain, fail-open like the rest); recordRejected's Domain is the login's too. The send log already counts a domain's messages by the login's domain (store.CountMessages, loginDomainID), so the limit and the count now agree. The null-sender special case is gone: every message is held to its login's domain. Tests: TestRateLimitIsNotReservedByAnotherSendersMailFrom (a stranger with no login; another tenant's application) - fails on the old code at the second MAIL FROM; the domain-limit tests sign in as app1 at example.com. e2e domain_limit_not_reserved_by_a_stranger: a domain with a limit of one, three unauthenticated MAIL FROM naming it on 465, then its own message passes and its second is refused 451. Docs: security.md § Mail path; CHANGELOG; plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -315,6 +315,9 @@ func TestE2E(t *testing.T) {
|
||||
run("rate_limit_refusal_is_notified", func(t *testing.T) {
|
||||
testRateLimitRefusalIsNotified(t, sc)
|
||||
})
|
||||
run("domain_limit_not_reserved_by_a_stranger", func(t *testing.T) {
|
||||
testDomainLimitNotReservedByAStranger(t, sc)
|
||||
})
|
||||
run("negative_sender_login_mismatch", func(t *testing.T) {
|
||||
testSenderLoginMismatch(t, sc)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user