1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2026-10-28 15:02:28 +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
+11 -3
View File
@@ -44,6 +44,9 @@ func TestDomain(t *testing.T) {
{"xn--aca-6ma", "ñaca"},
{"xn--lca", "ñ"}, // Punycode is for 'Ñ'.
{"e\u0301", "é"}, // Transform to NFC form.
{"a_b.c-d", "a_b.c-d"},
{"Trailing.Dot.", "trailing.dot."},
{"", ""},
}
for _, c := range valid {
nu, err := Domain(c.user)
@@ -56,7 +59,12 @@ func TestDomain(t *testing.T) {
}
invalid := []string{"xn---", "xn--xyz-ñ"}
invalid := []string{
"xn---", "xn--xyz-ñ",
"a/b", "a\\b", "a%2fb", "a b", "a\x00b", "a:b", "a@b",
"[1.2.3.4]", "[IPv6:::1]",
"ñ/b", // Non-ASCII label, ASCII characters are kept by Punycode.
}
for _, u := range invalid {
nu, err := Domain(u)
if err == nil {
@@ -85,7 +93,7 @@ func TestAddr(t *testing.T) {
}
invalid := []string{
"á é@i", "henry\u2163@throne", "a@xn---",
"á é@i", "henry\u2163@throne", "a@xn---", "a@b/c", "a@[1.2.3.4]",
}
for _, u := range invalid {
nu, err := Addr(u)
@@ -121,7 +129,7 @@ func TestDomainToUnicode(t *testing.T) {
}
}
invalid := []string{"a@xn---", "a@xn--xyz-ñ"}
invalid := []string{"a@xn---", "a@xn--xyz-ñ", "a@b/c", "a@[1.2.3.4]"}
for _, u := range invalid {
got, err := DomainToUnicode(u)
if err == nil {