CFMAIL e SPF

Se o seu site em ColdFusion oferece um recurso do tipo “envie para um amigo” ou qualquer outro que obrigue um usuário a fornecer um endereço de email e enviar algo para alguém utilizando seu site como meio, então você deve ler este post. Se você sabe o que é SPF, então pule direto para a parte “Como contornar isso no caso do CFMAIL?”.


No site Amazonia.org.br todas as notícias oferecem um recurso chamado “enviar notícias por email”. Ele é bastante simples (até demais) e existe por lá desde 2001, quando muitos usuários solicitavam esta função. Hoje o RSS suplanta isso, mas usuários menos experimentados ainda usam o “enviar notícia” com freqüência (nossos logs mostram isso claramente).

Este recurso de “enviar notícia” (ou qualquer outra informação, imagem, etc) pode se tornar falho. Devido a inúmeras técnicas e filtros anti-SPAM usados hoje em dia é possível que muitos de seus visitantes estejam utilizando o recurso de enviar “notícia/qualquer coisa”, mas as mensagens estejam sendo barradas no provedor para quem ele enviou a mensagem (que pode ser ele mesmo).

A principal razão (eu diria que 90%) dos bloqueios se deve ao uso do SPF (Sender Policy Framework) por parte do provedor do receptor da mensagem, coisa que a maioria dos provedores fazem (e eu recomendo que você também faça). Não é meu objetivo aqui explicar pormenorizadamente o que é e como funciona o SPF, mas em linhas gerais é mais ou menos assim (um exemplo):

O UOL, que detém o domínio UOL.COM.BR, publica uma informação em seus servidores DNS e esta informação (é um registro TXT simples) usa uma sintaxe padronizada (veja a documentação SPF) e que informa que para o domínio UOL.COM.BR, somente os servidores cujos IPs (pode ser um ou vários hostnames – veja a documentação) 200.221.4.130, 200.221.4.132 estão autorizados a enviar mensagens de email de seus usuários (por exemplo “voce@uol.com.br”). Vamos supor que a mensagem seja enviada para alguém com email no Terra. O Terra recebe a mensagem enviada por alguém do UOL (ex: de você@uol.com.br para seuamigo@terra.com.br) e vai checar nos registros SPF publicados pelo UOL para se certificar de a sua mensagem foi enviada por um dos SMTP autorizados pelo UOL. Se tiver sido enviado por um destes, ótimo, caso contrário ele irá barrar a mensagem, de acordo com o nível de falha (soft fail, fail, etc) configurado. Isso dificulta e impede o tão comum forjamento de emails para enviar SPAM através de um open relay ou mesmo de um SMTP server zumbi ou local (você já recebeu spam de você mesmo ou de alguém com email da sua empresa – seja um usuário existente ou não? Então…). O SPF é um framework com algumas falhas e contornável/burlável, mas ainda sim é um grande aliado no combate ao SPAM, especialmente nestes casos. Por isso você deve conhecê-lo se a sua aplicação faz envio de mensagens de terceiros (visitantes externos) para terceiros (visitantes externos).

Então, o que isso tem a ver com o recurso de “enviar notícia”? Oras, trata-se de uma relação de envio de mensagem de terceiro para terceiros. O SMTP usado pelo seu servidor ColdFusion será o SMTP de origem da mensagem/notícia enviada, e se o sujeito preencher o campo “Seu email:” com o email dele (que pode ser de qualquer provedor), teremos uma clara violação de SPF porque o provedor dele não autorizou (nos registros SPF deles) o seu servidor a enviar mensagem por por ele. A mensagem será bloqueada (no provedor de recepção) e dependendo do caso (existem administradores de sistema bem reacionários), seu servidor pode até ser reportado como uma fonte de SPAM e ir parar numa blacklist da vida (isso pode acontecer mesmo se você não proteger seus formulários de envio de mensagens – blogs que o digam!).

Como contornar isso no caso do CFMAIL?

A idéia é mimetizar o funcionamento de listas de discussão (que caem no mesmo problema do envio por terceiros para terceiros) e usar headers típicos para sua aplicação. A tag CFMAIL no ColdFusion 6.x (e versões mais novas) aceita algumas sintaxes interessantes no atributo “FROM” , entre elas uma variação que permite enviar mensagens, em nome de alguém (“On behalf”), exatamente como ocorre em listas de discussão. A sintaxe é:

FROM=”Nome do Visitante‹email@visitante.com.br› (by way of Seu Nome ‹seuemail@seuprovedor.com.br›)”

Onde necessariamente o SEUPROVEDOR.COM.BR do seuemail@seuprovedor.com.br deve ser de um domínio que autorize (via registros SPF) a geração e o envio de mensagens no seu SMTP.

Mas isso não é tudo. Para que a mensagem seja 100% SPF compliance, é necessário você configure um reverse-path no envelope da mensagem. Para isso existe o atributo FAILTO: da tag CFMAIL. Assim, a tag completa como exemplo ficaria:

‹CFMAIL TO=”amigo@terra.com.br” FROM=”Nome do Visitante‹email@uol.com.br› (by way of Seu Nome ‹seuemail@seuprovedor.com.br›)” FAILTO=”seuemail@seuprovedor.com.br” SUBJECT=”Envio de notícia”›

Se ainda você quiser incrementar, pode utilizar o atributo MAILERID e trocar o padrão que é “ColdFusion MX Application Server” (e pode ser barrado em alguns sistemas) para outro qualquer (por exemplo “Microsoft Outlook Express 6.00.2900.3028”). Mas cuidado, alguns sistemas anti-spam (o SpamAssassin por exemplo) identificam esta manobra e classificam-na como manipulação como sendo um fake mailerID. Eu sugiro que você utilize algo fora do comum, tal como o nome da sua empresa ou do seu site. “Sistema de envio de notícias – Nome do seu site” é uma boa sugestão. A regra básica é: não minta. 😉

Faça testes e veja as diferenças nos cabeçalhos dos emails. Utilizando estes recursos é muito provavel que a sua mensagem receba um Received-SPF: pass, liberando-a nos seus destinos.


6 Comments on “CFMAIL e SPF”

  1. Eu nunca usei ColdFusion, mas quando tenho que enviar emails via codificação de servidor (seja asp, php, jsp) eu uso uma estratégia diferente.

    No campo FROM eu deixo um email do meu proprio servidor: “contato@meuservidor.com”, mas no campo REPLY-TO eu coloco o email do usuário em questão que esta enviando a notícia.

    Muitos usuários comuns de internet quando recebem esse email clicam para responder sem ver o endereço que mandou a mensagem, e normalmente nem percebem que o remetente não é do seu amigo, mas com o reply-to o email do amigo dele já ira direto no FROM de sua resposta.

    Pronto, sempre usei essa tática e sempre funcionou!

    Abraços,
    William

  2. Alex Hubner disse:

    Você pode fazer exatamente isso também com o CF, basta usar o atributo REPLYTO da tag CFMAIL. Mas não é este o ponto deste post.

    A idéia é deixar o usuário (com o email dele) enviar a mensagem, e não você (com o seu email) enviar, de forma a não ser barrado pela proteção SPF. Por mais que o replyto seja diferente do remetente, será sempre uma gambiarra porque o campo FROM será sempre um email seu, e não do visitante.

    Conheça a tag CFMAIL:

    http://livedocs.adobe.com/coldfusion/7/htmldocs/00000297.htm

  3. Eu acredito que a verdadeira “gambiarra” seja o que você escreveu no seu post, pois o SPF foi feito justamente para barrar que qualquer pessoa envie um email em nome de outra, para evitar span e etc. O que esta tentando fazer é passar por cima disso.

    Um email enviado do seu servidor é um email enviado pelo SEU servidor. Mesmo que um usuário seu esteja mandando uma noticia sua pelo seu site, não é desculpa para usar o remetente dele, pois ele próprio pode estar colocando o email de outra pessoa no remetente e não o dele, não há como saber. Ou seja, o campo FROM tem de ser de quem enviou, ou seja, o SEU servidor.

    E não, obrigado, posso fazer isso em qualquer uma das outras 3 linguagens que já conheço, pelo menos por enquanto não preciso aprender ColdFusion ou CFMAIL.

    Mas se quiser, fique a vontade para conhecer JSP:

    http://java.sun.com/products/jsp/docs.html

  4. Alex Hubner disse:

    E você pode me dizer como funcionam as listas de discussão? O remetente de uma mensagem é sempre o do servidor que hospeda a lista? Para quê então existe o “on Bahalf”?

    Pelo que você disse acima, então o conceito de listas de discussão (e o funcionamento destas) é uma mera gambiarra, certo?

    Aliás, a idéia não é minha. A minha “gambiarra” é uma sugestão da próprio SPF Project – http://www.openspf.org/Best_Practices/Webgenerated, a única coisa que fiz foi mostrar como se pode fazer isso em CFML. Aliás, no artigo tem um exemplo em PHP. Talvez te seja útil…

    Antes de se sentir ofendido por pouco e dizer que estou (segundo suas palavras) “passando por cima” do SPF (quando na realidade estou mostrando exatamente como ser fiel e aderente a ele), se acalme, leia de novo (se necessário) e tente outra vez.

    PS: conheço JSP e Java. Aliás, posso usá-los e invocá-los nativamente dentro de um script CFML. Te mandei o link para que você pudesse conhecer a tag CFMAIL e os seus atributos, apenas isso. Mas pelo visto isso te ofendeu. Desculpe, não era a intenção.

  5. Sugiro que se quer leitores que participem do assunto nos comentários não chame de “gambiarra” as sugestões dos mesmos.

    Não, não me senti ofendido, apenas tomei a liberdade de responder no mesmo nível que você.

    Estou apenas dando minha opinião e não, eu não sei de tudo e posso estar errado (ooohh =P ).

    Agora sobre as listas de discussões, de qualquer forma, quem enviu o email foi comprovadamente você, o que (na minha visão) da a liberdade para o servidor completar o serviço e reenviar para todos da lista. Fora que são servidores próprios para isso e provavelmente os hosts que fazem isso devem estar em uma lista especial dentro da SPF.

    Como você mesmo disse em seu post, já que me recomendou lê-lo novamente:

    “Mas cuidado, alguns sistemas anti-spam (o SpamAssassin por exemplo) identificam esta manobra e classificam-na como manipulação como sendo um fake mailerID”

    Ou seja, mesmo se for uma sugestão do SPF, não me parece confiável, mesmo se não for uma “gambiarra”.

  6. Alex Hubner disse:

    1) O que o SpamAssassin identifica como manipulação é apenas a modificação do mailer-ID.

    2) Em uma lista de discussão, quem participa recebe sempre a mensagem originada no SMTP do servidor, jamais do SMTP de quem enviou a mensagem para a lista.

    3) Não existe “lista especial” ou algo do gênero “na SPF”. Sender Policy Framework, como o próprio nome já diz é uma técnica. Não é uma organização/empresa que mantenha listas ou coisas do gênero.

    Acho que realmente você não sabe o que está falando. Refaço minha sugestão: leia e se informe antes de dizer (ou ensinuar) que a técnica ensinada aqui está errada ou pode ser suplantada por uma mera gambiarra (e desculpe, eu continuo achando uma mera gambiarra a sua sugestão para lidar com SPF em emails enviados por sites). O termo não é pejorativo desde que você não sofra de orgulho exacerbado.

    [1] http://desciclo.pedia.ws/wiki/POG