Quem gerencia servidores de e-mail e monitora o tráfego que atinge os filtros de borda sabe que a comunicação entre sistemas só funciona com estabilidade quando todo mundo respeita as mesmas especificações. No cenário ideal da internet moderna, o padrão UTF-8 comanda o tráfego global. Na prática do dia a dia, no entanto, frequentemente me deparo com cabeçalhos malformados e codificações jurássicas geradas por aplicações antigas que se recusam a morrer.
Recentemente, capturei nos meus filtros de borda um lote de mensagens geradas por um sistema automatizado que ilustra esse problema com perfeição. O remetente reclamava que seus relatórios financeiros não chegavam aos destinatários, sumiam no trajeto ou eram sumariamente empurrados para as caixas de lixo eletrônico.
Ao abrir o cabeçalho bruto da mensagem para investigar, a causa raiz ficou evidente: o e-mail continha uma combinação clássica de violações de normas RFC e codificação legada que transformava o envio em um verdadeiro "e-mail zumbi" aos olhos dos filtros modernos de segurança (como SpamAssassin e SPFBL).
Abaixo, compartilho a análise forense de cada uma dessas falhas e o código funcional para corrigir o problema direto na aplicação e nos servidores receptores.
O fragmento de cabeçalho analisado#
Para manter o caso estritamente confidencial, anonimizei as contas e domínios envolvidos, preservando a sintaxe e a estrutura exatas capturadas no log:
From: remetente@domain.com.br
To: destino@empresa.com.br
Cc: gestor@empresa.com.br; auditor@empresa.com.br
Subject: Relatorio de Faturamento - Marco
Content-Type: text/plain; charset=ISO-8859-1
[Corpo da mensagem com acentos em ISO-8859-1 bruto]
À primeira vista, parece uma mensagem comum de rotina corporativa. No entanto, para o parser de um agente de transferência de mensagens (MTA), esse cabeçalho contém três violações graves de protocolo.
Análise técnica das violações de RFC#
1. Ausência crítica do cabeçalho Message-ID#
A mensagem falhou em incluir o identificador de mensagem. De acordo com a RFC 5322 (Internet Message Format), na seção 3.6.4, mensagens transmitidas pela internet devem conter um identificador globalmente exclusivo (especificado formalmente como SHOULD, embora na prática os filtros modernos e gateways de e-mail tratem como obrigatório):
message-id = "Message-ID:" msg-id CRLF
O Message-ID é essencial para:
- Evitar loops infinitos de retransmissão em filas de entrega do MTA.
- Manter a rastreabilidade e a correlação em threads de conversação (
In-Reply-ToeReferences). - Construir a cadeia de custódia e logs de auditoria.
Quando um script caseiro abre um socket direto para envio de e-mail e não injeta o Message-ID (esperando que o servidor receptor "adivinhe" o identificador), o filtro antispam de destino aplica imediatamente uma penalidade pesada (como a regra MISSING_MID do SpamAssassin). Em plataformas que adotam políticas rígidas de filtragem, mensagens sem esse identificador são sumariamente rejeitadas com erro 550 ou enviadas direto para a quarentena.
2. Assunto com acentuação em ISO-8859-1 bruto (violação da RFC 2047)#
No cabeçalho capturado, o campo de assunto continha caracteres acentuados gravados diretamente no padrão ISO-8859-1 (Latin-1).
A especificação original do SMTP exige que os cabeçalhos de e-mail contenham exclusivamente caracteres US-ASCII de 7 bits. Para contornar essa barreira histórica e permitir palavras acentuadas em qualquer idioma, foi estabelecida a RFC 2047, que define a sintaxe padronizada de MIME Encoded-Word:
$$\text{=?charset?encoding?encoded-text?=}$$
Para enviar a string "Relatório de Faturamento - Março" de forma válida em UTF-8 usando codificação Base64 (B), a representação obrigatória no cabeçalho deve ser:
Subject: =?UTF-8?B?UmVsYXTDs3JpbyBkZSBGYXR1cmFtZW50byAtIE1hcsOnbw==?=
Quando um script joga caracteres Latin-1 brutos sem essa estrutura, o leitor de e-mail do destinatário falha na interpretação dos bytes. O resultado é o clássico erro visual de caracteres corrompidos (mojibake), com a exibição de símbolos ilegíveis como ç ou �, além de acionar regras heurísticas de antispam que punem cabeçalhos não conformes com a RFC.
3. Delimitador incorreto no campo Cc (ponto e vírgula em vez de vírgula)#
No cabeçalho analisado, os destinatários em cópia foram formatados desta maneira:
Cc: gestor@empresa.com.br; auditor@empresa.com.br
Pelas especificações da RFC 5322, listas de endereços nos campos To, Cc e Bcc devem ser obrigatoriamente separadas por vírgula (,):
Cc: gestor@empresa.com.br, auditor@empresa.com.br
O uso do ponto e vírgula é um vício de interface herdado de versões antigas do Microsoft Outlook desktop. O Outlook aceita o ponto e vírgula na digitação do usuário e converte para vírgula internamente antes da transmissão.
Porém, quando desenvolvedores montam scripts próprios e copiam esse comportamento diretamente para a camada de transporte SMTP, o parser do servidor receptor se perde. Ele tenta interpretar o ponto e vírgula como parte do nome da caixa postal, falha na validação sintática do endereço e quebra o roteamento da mensagem para os destinatários em cópia.
Por que o ISO-8859-1 ainda assombra a infraestrutura?#
Em uma época em que o UTF-8 é o padrão absoluto da web, por que codificações como o Latin-1 ainda aparecem nos logs? Na minha experiência, isso acontece por dois motivos principais:
- Sistemas e ERPs legados: Aplicações de faturamento, módulos de geração de relatórios e rotinas de emissão de NF-e desenvolvidas há mais de quinze anos. Enquanto o motor de banco de dados funciona, poucas empresas revisam os scripts de disparo de e-mail.
- *Má configuração de ambiente (Locale): Scripts modernos em PHP ou Python rodando em servidores cujo locale* do sistema operacional ou do banco de dados ainda opera em ISO-8859-1. Se o desenvolvedor utiliza funções nativas de envio sem declarar explicitamente o
charset=utf-8e a codificação RFC 2047, o interpretador faz o fallback automático para a tabela regional antiga da máquina.
Clientes de e-mail comerciais e modernos (Thunderbird, Gmail, Outlook Web) jamais geram essa estrutura corrompida. Quase a totalidade desses incidentes tem origem em automações internas sem manutenção técnica.
Como corrigir na camada de aplicação (PHP)#
Para resolver esse problema na origem, construí uma implementação limpa em PHP que garante conformidade estrita com as RFCs 5322 e 2047:
<?php
declare(strict_types=1);
$to = 'destino@empresa.com.br';
$ccList = [
'gestor@empresa.com.br',
'auditor@empresa.com.br'
];
// 1. Correção: Delimitar múltiplos destinatários estritamente por VÍRGULA
$ccHeader = implode(', ', $ccList);
// 2. Correção: Codificar o Subject conforme a RFC 2047 (UTF-8 em Base64)
$rawSubject = 'Relatório de Faturamento - Março';
$encodedSubject = '=?UTF-8?B?' . base64_encode($rawSubject) . '?=';
// 3. Correção: Gerar Message-ID único e definir charset UTF-8 explícito
$messageId = sprintf('<%s.%s@domain.com.br>', bin2hex(random_bytes(16)), time());
$headers = [
'From' => 'remetente@domain.com.br',
'Cc' => $ccHeader,
'MIME-Version' => '1.0',
'Content-Type' => 'text/plain; charset=UTF-8',
'Content-Transfer-Encoding' => '8bit',
'Message-ID' => $messageId,
'X-Mailer' => 'PHP/' . phpversion()
];
// Montagem dos cabeçalhos em formato string compatível com mail()
$headersString = '';
foreach ($headers as $key => $value) {
$headersString .= "{$key}: {$value}\r\n";
}
$body = "Prezados,\r\n\r\nSegue o relatório consolidado referente ao fechamento de março.\r\n";
// Disparo em conformidade com as normas
mail($to, $encodedSubject, $body, $headersString);
Com essas correções simples:
- O assunto é lido perfeitamente sem caracteres quebrados em qualquer dispositivo.
- O campo
Ccentrega as mensagens para todos os envolvidos sem erro de parsing. - O
Message-IDgarante trânsito livre nos gateways de antispam.
Tratamento no servidor receptor com Postfix#
Se você gerencia o servidor de destino e precisa detectar e penalizar mensagens malformadas antes que cheguem às caixas dos usuários, o Postfix oferece a diretiva header_checks.
No arquivo /etc/postfix/header_checks, é possível adicionar regras de expressões regulares para capturar mensagens zumbis:
# Alerta ou rejeição de mensagens com ponto e vírgula no Cc
/^Cc:.*;/ WARN Cabecalho Cc malformado com ponto e virgula (violacao RFC 5322)
# Quarentena ou descarte de mensagens sem Message-ID
!/^Message-ID:/ WARN Mensagem recebida sem cabecalho Message-ID obrigatorio
Ao utilizar tabelas de padrões regulares (header_checks = pcre:/etc/postfix/header_checks ou regexp:), o arquivo não necessita de indexação com postmap. Basta recarregar o serviço:
sudo systemctl reload postfix
Como auditar seus envios e garantir entregabilidade máxima#
Antes de culpar os filtros de segurança do destinatário ou achar que o domínio foi parar em uma blacklist sem motivo, o primeiro passo deve ser sempre a auditoria do cabeçalho bruto:
- Abra o e-mail original: No cliente de e-mail, acesse a opção Ver código-fonte ou Exibir original.
- Cheque o Message-ID: Verifique se ele existe, se possui o formato
<identificador@seudominio>e se o domínio bate com o remetente. - Valide a codificação do Subject: Palavras acentuadas devem obrigatoriamente estar envelopadas na estrutura
=?UTF-8?B?...?=ou=?UTF-8?Q?...?=. - Verifique os separadores de listas: Jamais use ponto e vírgula nos campos de destinatários.
Garantir que suas aplicações gerem cabeçalhos em conformidade estrita com os padrões RFC é a maneira mais eficaz e sustentável de manter a reputação do seu servidor impecável e evitar que mensagens legítimas sejam tratadas como ameaças.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários