fix(sieve): reconhece endereços automáticos com sufixo

Encontrado a correr o script guardado na caixa real antes de o pôr no
ar. O Google envia os relatórios DMARC de
noreply-dmarc-support@google.com, e a verificação só reconhecia a
palavra exacta ou um sufixo com "+": a caixa teria respondido
automaticamente a todos os relatórios diários que recebe.

O prefixo passa a ser comparado com os separadores que os remetentes
usam de facto - "+", "-", "." e "_" - e a lista cresce com os nomes
correntes deste tipo de endereço. Continua a responder a uma pessoa
cujo endereço apenas começa por uma dessas palavras, o que também tem
teste: "bouncer" é gente, "bounces-123" não é.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Opus 5 committed 2026-08-22 13:49:33 -03:00
1 parent d403c47a71
commit caec501ec5
2 files changed
+58 -2

No files matched your search

@@ -392,3 +392,44 @@ func TestEscapedQuestionMarkIsALiteralCharacter(t *testing.T) {
t.Errorf("the escaped question mark matched any character: %q", out.Folder)
}
}
// A reserved local part is recognised however the sender joined it to the rest
// of the address.
//
// Found by running the script stored on a real mailbox: Google sends its DMARC
// reports from noreply-dmarc-support@google.com, and matching only the exact
// word or a "+" suffix let that through - so the responder would have replied
// to every daily report, forever.
func TestVacationStaysSilentForReservedAddressesWithSuffixes(t *testing.T) {
senders := []string{
"noreply-dmarc-support@google.com",
"no-reply.billing@example.test",
"bounces+abc123@example.test",
"mailer-daemon@example.test",
"notifications-noreply@example.test",
"MAILER-DAEMON@EXAMPLE.TEST",
}
for _, sender := range senders {
out := evaluate(t, vacationScript, Message{
Sender: sender,
Headers: map[string][]string{"from": {sender}},
})
if out.Vacation != nil {
t.Errorf("would have replied to %s", sender)
}
}
}
// The guard must not swallow a real person whose address merely starts with
// one of those words.
func TestVacationStillRepliesToAPersonWithASimilarAddress(t *testing.T) {
for _, sender := range []string{"noreplygames@example.test", "bouncer@example.test", "postmasters@example.test"} {
out := evaluate(t, vacationScript, Message{
Sender: sender,
Headers: map[string][]string{"from": {sender}},
})
if out.Vacation == nil {
t.Errorf("stayed silent for %s, which is a person", sender)
}
}
}