Bom pessoal, eu vou falar sobre um assunto que não é muito discutido e que muitos programadores até ignoram. O Mail Injection, que é uma forma de burlar um sistema de envio de e-mails em PHP, normalmente enviando spans a partir do servidor no qual o sistema esteja instalado. Isto pode denegrir a imagem de uma empresa, dentre outros problemas. Para saber mais, visite esta wiki que explica melhor.
Para começar vamos explicar o funcionamento da função mail(), a qual é nativa do php. Ela tem cinco parâmetros:
- to > Endereço que irá receber o e-mail;
- subject > Assunto da mensagem;
- message > O corpo da mensagem;
- additional_header > cabeçalhos adicionais(Com Cópia, Cópia Oculta, dentre outros cabeçalhos);
- additional_parameters > usado para passar parametros para o programa que gerencia os e-mails.
Dentre estes campos, nós vamos nos preocupar com o to, o subject e o additional_header. Visto que os três são usados para incluir dados ao cabeçalho do e-mail.
Vamos a um exemplo, onde será mostrada a mensagem produzida pela execução da função mail:
mail('meiocodigo@gmail.com',$_GET['subject'],$_GET['message'],"From: ".$_GET['from']);
A função acima é largamente utilizada, visto que ele pega de um formulário o assunto, a mensagem e o remetente e envia por e-mail para um endereço fixo definido pelo progrador. Vamos supor que os valores de $_GET sejam como abaixo:
$_GET['subject'] = 'Post sobre Mail Injection';
$_GET['message'] = 'Pode tirar uma dúvida sobre o post sobre mail injection...';
$_GET['from'] = 'alguem@algumemail.com';
A mensagem produzida pela função supra-citada seria:
To: meiocodigo@gmail.com
Subject: Post sobre Mail Injection
From: alguem@algumemail.com
Pode tirar uma dúvida sobre o post sobre mail injection… Note que o formato gerado é:
To: $to
Subject: $subject
$additional_headers
$message
Até aqui está tudo certo, nenhum problema com o nosso código. Mas imagine se alguem insere o seguinte valor para Subject: ‘Assunto%0ACc: outro@email.com%0ABcc: maisoutro@email.com’. Essa String tem o mesmo valor que:
Assunto
Cc: outro@email.com
Bcc: maisoutro@email.com
Colocando isso no texto criado pela função mail nós temos:
To: meiocodigo@gmail.com
Subject: Assunto
Cc: outro@email.com
Bcc: maisoutro@email.com
From: alguem@algumemail.com
Pode tirar uma dúvida sobre o post sobre mail injection… Note que o arquivo gerado tem mais 2 itens no cabeçalho: um email para ser enviado como cópia; e outro como cópia oculta. É dessa forma que o formulário de e-mail é usado para fazer ataques de span. O detalhe é que o cabeçalho tem como separador a quebra de linha, ou seja, só é considerado um novo item do cabeçalho caso haja uma quebra de linha. Isso justifica o uso do %0A, que é o código hexadecimal da quebra de linha.
O que foi explicado acima se aplica a qualquer um dos três campos citados que fazem parte do cabeçalho.
Para resolver isso, eu criei uma função que checa se existem caracteres de quebra de linha nas strings de cabeçalho, retornando false, caso encontre:
function check_mail_injection($string){
if(strpos($string,'\n') !== false) return false;
if(strpos($string,'\r') !== false) return false;
if(strpos($string,'%') !== false) return false;
return true;
}
Quero dedicar os créditos dessa função ao meu amigo Edson Aníbal da Superintendência de Informática da UFRN, que foi quem fez o procedimento, eu apenas encapsulei em uma função.
Vamos entender a função, ela pega uma $string, e verifica a existência de um caractere ‘\n’, ‘\r’ ou ‘%’. Os dois primeiros representam quebra de linha. E o ‘%’ pode ser usado para representar o código hexadecimal da quebra de linha.
Só mais um detalhe, não é recomendável aplicar essa função ao corpo da mensagem, visto que a mesma pode conter quebras de linha.
Espero ter sido claro. Qualquer dúvida coloca nos comentários.

May 26th, 2007 12:25
Muito bom o post, nunca tinha pensado nisso… vou tomar mais cuidado com os envios de e-mail agora.
May 26th, 2007 16:05
vou prestar atenção. valeu galera.
May 26th, 2007 17:31
Eh Muito Bom!!!! Vcs me Salvaram legal, estava precisando disso!!
June 2nd, 2007 12:57
Ótimo post, só faço uma resalva de uma outra forma de mail injection q é na hora de um usuário preencher o cadastro de e-mail (pro exemplo ao se cadastrar em uma newsletter).
Isso pq o primeiro parâmetro da função mail aceita vários emails separados por vírgula, então se ele colocar uma string com muitos email (provavelmente só pra ver o mal mesmo…) o servidor enviaria para todos esses emails.
Pra resolver isso é só não inserir o registro onde são encotradas por exemplo duas @’s, q ficaria constatado dois emails, ou uma ou mais vírgulas…
valew galera
September 26th, 2008 17:55
Galera, passeei um pouco pelo blog novo aqui e a qualidade tá muito boa. Se for possível (e do agrado de vocês) gostaria de dar mais visibilidade a algumas materias aqui postando elas lá no fórum Webly: forum.ievolutionweb.com Claro que com os devidos créditos e link no início e final.
September 26th, 2008 19:05
Obrigado a todos pelos comentários e pelo reconhecimento do trabalho.
@Micox quanto a divulgar o conteúdo, fique a vontade, a única ressalva é a divulgação dos créditos, que por sinal você já falou que iria fazê-la.
May 10th, 2009 19:19
Boa noite Vinicius,
Estou estudando PHP, gostaria de saber o significado deste operador “!==” na função check_mail_injection, pois não tenho conhecimento.
Agradeço desde já, Junio César Silva
May 10th, 2009 21:57
Junio, o operador ‘!==’ significa realmente diferente. O PHP considera 0 igual a uma string vazia, ou a false. Então:
0 != ” retorna false
0 !== ” retorna true
May 14th, 2009 06:36
Muito obrigado Vinicius, sua explicação foi de grande valia.Paz e saúde para ti.
November 29th, 2010 23:39
Utilize expressões regulares, fica menor!
preg_match(“/[\n\r%]/”,$string)