1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2026-10-29 15:02:30 +00:00

Reject invalid characters in domains

Domains in addresses had very lax validation, which allowed them to
include characters like "/".

That could be exploited to trigger a daemon panic: a MAIL FROM
"x@evil/foo" could be accepted and, on failed delivery, a DSN queued.
Attempting to deliver the DSN would cause an MTA-STS cache lookup, which
would panic because the domain includes a "/" and crash the server.
Because the DSN would be queued, the server would crash again on
restarts, and only self-recover after give_up_send_after (20h by
default).

To fix this, we now explicitly validate the domain when normalizing it,
make MTA-STS cache not panic on invalid domains, and also make the SMTP
courier fail permanently on invalid domains.

Thanks to John JEAN <john@wargan.com> for finding and reporting this
problem. The detailed report can be found in
https://johnjean.io/advisories/chasquid-unauthenticated-remote-dos/.
This commit is contained in:
Alberto Bertogli
2026-10-08 23:54:15 +01:00
parent d2260180c6
commit 61792e3bb4
14 changed files with 255 additions and 35 deletions
+12 -7
View File
@@ -473,6 +473,16 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
return 501, "5.1.7 Sender address too long"
}
// Normalize (and validate) the address before doing any lookups.
// Note SPF and the security level check use the address as given,
// and we only use the normalized version from then on.
normAddr, err := normalize.DomainToUnicode(addr)
if err != nil {
maillog.Rejected(c.remoteAddr, addr, nil,
fmt.Sprintf("malformed address: %v", err))
return 501, "5.1.8 Malformed sender domain"
}
// SPF check - https://tools.ietf.org/html/rfc7208#section-2.4
// We opt not to fail on errors, to avoid accidents from preventing
// delivery.
@@ -491,12 +501,7 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
return 550, "5.7.3 Security level check failed"
}
addr, err = normalize.DomainToUnicode(addr)
if err != nil {
maillog.Rejected(c.remoteAddr, addr, nil,
fmt.Sprintf("malformed address: %v", err))
return 501, "5.1.8 Malformed sender domain (IDNA conversion failed)"
}
addr = normAddr
}
c.mailFrom = addr
@@ -595,7 +600,7 @@ func (c *Conn) RCPT(params string) (code int, msg string) {
addr, err := normalize.DomainToUnicode(e.Address)
if err != nil {
return 501, "5.1.2 Malformed destination domain (IDNA conversion failed)"
return 501, "5.1.2 Malformed destination domain"
}
// https://tools.ietf.org/html/rfc5321#section-4.5.3.1.3