Como evitar a injeção SMTP: uma introdução à análise white-box
Sam Sanoop
15 de setembro de 2022
0 minutos de leituraAs vulnerabilidades de injeção SMTP costumam ser mal compreendidas por desenvolvedores e profissionais de segurança, além de passarem despercebidas por ferramentas de análise estática. Neste artigo, vamos explicar como vulnerabilidades comuns de injeção SMTP podem existir em bibliotecas e aplicações e trazer dicas para encontrá-las e corrigi-las rapidamente.
Introdução ao SMTP
O Simple Mail Transfer Protocol (SMTP) é um protocolo de e-mail usado para enviar e receber mensagens. Clientes de e-mail usados pelos usuários normalmente utilizam o SMTP para enviar mensagens a um servidor de e-mail, que as retransmite. Os servidores SMTP costumam usar o Transmission Control Protocol nas portas 25 (para texto sem criptografia) e 587 (para comunicações criptografadas).
Softwares e aplicações modernos costumam usar o protocolo SMTP em etapas do fluxo de uso e enviar e-mails em resposta a ações do usuário. Um exemplo são os e-mails de confirmação de cadastro, que podem incluir o endereço de e-mail do usuário e um texto de boas-vindas predefinido, e retransmitir essa mensagem a um servidor SMTP para que ela seja enviada à conta de e-mail do usuário.
Durante uma sessão SMTP entre um cliente e um servidor SMTP, o cliente pode usar vários comandos. Veja alguns exemplos comuns:
HELO/EHLO- O comandoHELOinicia a comunicação da sessão SMTP. Por exemplo:HELO snyk.io.MAIL FROM- O comandoMAIL FROMinicia a transferência de e-mail e especifica um endereço de origem. Por exemplo:MAIL FROM "[foo@snyk.io](mailto:foo@snyk.io)".RCPT TO- O comandoRCPT TOespecifica o destinatário do e-mail. Por exemplo:RCPT TO "[foobar@snyk.io](mailto:foobar@snyk.io)".DATA- Com o comandoDATA, o cliente solicita permissão ao servidor para transferir os dados do e-mail. O código de resposta 354 concede essa permissão, e o cliente inicia o envio do conteúdo do e-mail, linha por linha. A transmissão deDATApode ser encerrada com o caractere.
Veja abaixo um exemplo de comunicação SMTP entre um cliente e um servidor.
O que é injeção SMTP
A injeção SMTP pode ocorrer quando um invasor consegue inserir comandos SMTP arbitrários em uma comunicação SMTP entre um cliente e um servidor. Isso pode acontecer por meio da inserção de caracteres CRLF adicionais em parâmetros controlados pelo usuário, que podem ser incluídos em um comando SMTP sem validação ou sanitização adequada.
Esses casos costumam ocorrer em aplicações web que usam bibliotecas para enviar comandos SMTP ou têm implementações internas que não validam os parâmetros controlados pelo usuário.
O impacto da injeção SMTP pode variar de acordo com o contexto da aplicação afetada. Entre os impactos mais comuns estão:
Enviar cópias de e-mails a terceiros.
Modificar o conteúdo da mensagem enviada ao servidor SMTP.
Usar a aplicação afetada pela injeção SMTP como proxy para realizar ataques de phishing.
Para entender melhor a injeção SMTP, vamos analisar os exemplos a seguir.
Cenário 1 de injeção SMTP
Desenvolvedores costumam usar bibliotecas de terceiros para enviar e-mails a um servidor SMTP, como alternativa às funções SMTP das bibliotecas padrão. Um exemplo é a smtp-client. A smtp-client oferece vários campos para definir o nome do host, a autenticação, o destinatário e os remetentes, que podem então ser enviados como parte de uma mensagem SMTP.
No entanto, considere um cenário em que não é possível definir o campo s.rcpt e somente o campo s.mail é controlado pelo usuário. Nesses casos, os caracteres CRLF podem ser usados para inserir um novo comando, como from@sender.com>\r\nRCPT TO:<[attacker@snyk.io](mailto:attacker@snyk.io).
Exemplo:
Como não houve validação, o cliente SMTP processa os caracteres CRLF e interpreta RCPT TO:<[attacker@snyk.io](mailto:attacker@snyk.io) como um novo comando SMTP. A imagem a seguir mostra esse comando sendo aceito por um servidor SMTP.

Além da smtp-client, a Snyk também encontrou vulnerabilidades de injeção SMTP em vários campos dos pacotes Perl Email MIME e Net::SMTP. O problema de segurança foi reportado aos responsáveis pela manutenção das bibliotecas, e as versões mais recentes desses pacotes já incluem correções.
Cenário 2 de injeção SMTP
Também existem bibliotecas de baixo nível em vários ecossistemas de linguagens de programação que desenvolvedores podem usar para se comunicar com um servidor SMTP. Um exemplo é a smtp-channel.
No caso da smtp-channel, desenvolvedores podem criar e-mails para usuários usando dados fornecidos por eles e passar esses dados para a smtp-channel como um fluxo. Nesses casos, um invasor pode adicionar cabeçalhos e usar a sessão SMTP existente para falsificar um e-mail. O código a seguir demonstra o problema:
Cenário 3 de injeção SMTP
Bibliotecas de criação de e-mails usadas em conjunto com clientes SMTP também podem ser afetadas pela injeção SMTP. Um exemplo desse problema está no pacote Python email, uma biblioteca para gerenciar mensagens de e-mail. Nesse caso, é possível realizar uma injeção SMTP fornecendo caracteres CRLF ao campo mail.headerregistry.Address.
A imagem a seguir mostra o comando RCPT existente sendo encerrado com o caractere > e um novo cabeçalho cC sendo injetado com \r\n. Ele será enviado como um novo comando RCPT, como mostrado abaixo.

Vale destacar que a equipe de segurança do Python corrigiu essa vulnerabilidade nas versões 3.X. Clique aqui para ver as notas de lançamento completas. No entanto, as versões 2.X continuam vulneráveis.
Cenário 4 de injeção SMTP
Ao investigar vulnerabilidades de injeção SMTP, vale lembrar que outros campos, como o nome do host e o endereço de origem, também podem aceitar caracteres CRLF e, portanto, permitir uma injeção SMTP.
No exemplo a seguir, os campos From e To fornecidos ao aiosmtplib são sanitizados. No entanto, ainda é possível injetar dados em source_address e inserir um comando SMTP arbitrário. Veja abaixo a prova de conceito (PoC) que demonstra o problema:
Isso gera a seguinte comunicação SMTP.

Outros casos a considerar
Em algumas situações, bibliotecas de e-mail também podem permitir a execução de código. Um exemplo é a função mail(). Se uma entrada fornecida pelo usuário chegar ao quinto parâmetro da função mail(), um invasor poderá explorá-la para executar código. Clique aqui para ver um exemplo desse problema.
As vulnerabilidades de injeção SMTP costumam ser confundidas com vulnerabilidades de injeção de e-mail. Em uma vulnerabilidade de injeção de e-mail, um invasor pode explorar um recurso de envio de mensagens usando uma função SMTP para enviar e-mails arbitrários e realizar ataques de phishing. Já na injeção SMTP, caracteres CRLF são usados para inserir cabeçalhos arbitrários, que podem então ser usados para falsificar e-mails e realizar ataques de phishing.
Como prevenir a injeção SMTP
A injeção SMTP é uma vulnerabilidade que desenvolvedores e responsáveis pela manutenção de bibliotecas open source muitas vezes deixam passar. Na maioria dos casos, a correção deve ser feita pelos responsáveis pela manutenção das bibliotecas. Muitas bibliotecas conhecidas, como JavaMail, PHPMailer e RubyMail, já previnem a injeção SMTP ao sanitizar caracteres CRLF. Em bibliotecas de baixo nível, como smtp-channel, cabe ao desenvolvedor que usa a biblioteca validar e sanitizar os dados de entrada fornecidos pelo usuário.
Para ajudar a tornar a comunidade open source mais segura, a equipe de segurança da Snyk também divulgou vulnerabilidades de injeção SMTP nas bibliotecas a seguir.
Biblioteca | Linguagem | Versão corrigida |
|---|---|---|
| C | Corrigido na versão Master |
| Perl | Não há correção disponível |
| Perl | Não há correção disponível |
| Python | Corrigido na versão 1.1.7 |
| NodeJS | Não há correção disponível |
Comece a resolver desafios de capture the flag
Aprenda a resolver desafios de capture the flag assistindo sob demanda ao nosso workshop virtual introdutório.
