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:
@@ -225,7 +225,8 @@ func TestBrokenAuth(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWrongMailParsing(t *testing.T) {
|
||||
addrs := []string{"from", "a b c", "a @ b", "<x>", "<x y>", "><"}
|
||||
addrs := []string{"from", "a b c", "a @ b", "<x>", "<x y>", "><",
|
||||
"a@b/c", "a@[1.2.3.4]"}
|
||||
for _, addr := range addrs {
|
||||
c := mustDial(t, ModeSMTP, false)
|
||||
|
||||
@@ -247,6 +248,32 @@ func TestWrongMailParsing(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMalformedDomain(t *testing.T) {
|
||||
// Unauthenticated MAIL FROM.
|
||||
c := mustDial(t, ModeSMTP, false)
|
||||
defer c.Close()
|
||||
|
||||
err := c.Mail("a@b/c")
|
||||
expectTPErr(t, err, 501, "5.1.8 Malformed sender domain")
|
||||
|
||||
// Authenticated RCPT TO. We need to authenticate, otherwise it may get
|
||||
// rejected as relaying.
|
||||
c = mustDial(t, ModeSubmission, true)
|
||||
defer c.Close()
|
||||
|
||||
auth := smtp.PlainAuth("", "testuser@localhost", "testpasswd", "127.0.0.1")
|
||||
if err := c.Auth(auth); err != nil {
|
||||
t.Fatalf("Auth: %v", err)
|
||||
}
|
||||
|
||||
if err := c.Mail("testuser@localhost"); err != nil {
|
||||
t.Fatalf("Mail: %v", err)
|
||||
}
|
||||
|
||||
err = c.Rcpt("a@b/c")
|
||||
expectTPErr(t, err, 501, "5.1.2 Malformed destination domain")
|
||||
}
|
||||
|
||||
func TestNullMailFrom(t *testing.T) {
|
||||
c := mustDial(t, ModeSMTP, false)
|
||||
defer c.Close()
|
||||
|
||||
Reference in New Issue
Block a user