|
Agora que você já leu sobre o problema e sobre como o php mail() funciona, é hora da segurança.
A primeira - e óbvia - solução para o php mail() injection é usar outro mailer como o zend_mail ou o pear mail para enviar as mensagens. Mas, se você já tem um script pronto e funcionando com o php mail(), esta solução não é tão prática.
Outra solução não tão prática e que você normalmente encontrará ao fazer pesquisas sobre este assunto é instalar o mod_security no seu servidor e mandá-lo analisar todas as requisições POST e GET, procurar por bcc:, cc:, e to: e negar estas solicitações. Se você escolher esta solução, adicione a seguinte regra ao setup do mod_segurity:
SecFilterSelective ARGS_VALUES "\n[[:space:]]*(to|bcc|cc)[[:space:]]*:.*@"
Nossa solução favorite consiste no uso de regular expressions (regexps) para filtrar os dados do formulário em conjunto com campos registrados. Primeiro, vamos dar uma olhada em exemplos de como regexps podem ser usadas para para e-mail injection. Abaixo você encontrará alguns exemplos de filtros com regexp e uma descrição do que cada um faz. Troque $field pelo nome do campo que você deseja filtrar.
Parar se o campo contém qualquer ocorrência de "\r" ou "\n".
if (eregi("(\r|\n)", $field)) {
die("Get out, spammer.");
}
Parar se o formato do e-mail informado é inválido.
if(!eregi("^[a-z0-9]+([_\\.-][a-z0-9]+)*" ."@"."([a-z0-9]+([\.-][a-z0-9]+)*)+"."\\.[a-z]{2,}"."$",$field))
{
die("Formato de e-mail invalido.");
}
Parar se existir uma @ (arroba) no campo.
if(eregi("@",$field)){
die("Invalid content for this field.");
}
Parece simples de implementar? Realmente é.
Se você usar regexps para filtrar seus scripts em associação com campos registrados, seu script será quase à prova de mail injection. Para registrar os campos do seu formulário, siga os dois simples passos descritos a seguir.
Passo 1: Crie um arquivo com o conteúdo abaixo para ser incluído pelo seu script. No nosso exemplo o nome do arquivo será "stopinjection.inc.php".
<?php
function regfld()
{
$num_args = func_num_args();
$vars = array();
if ($num_args >= 2) {
$method = strtoupper(func_get_arg(0));
if (($method != 'SESSION') && ($method != 'GET') && ($method != 'POST') && ($method != 'SERVER')
&& ($method != 'COOKIE') && ($method != 'ENV')) {
die('The first argument of regfld must be one of the following: GET, POST, SESSION, SERVER,
COOKIE, or ENV');
}
$varname = "HTTP_{$method}_VARS";
global ${$varname};
for ($i = 1; $i < $num_args; $i++) {
$parameter = func_get_arg($i);
if (isset(${$varname}[$parameter])) {
global $$parameter;
$$parameter = ${$varname}[$parameter];
}
}
} else {
die('You must specify at least two arguments');
}
}
?>
Passo 2: Agora adicione as linhas a seguir no seu script. Este código irá verificar se pelo menos dois campos foram preenchidos, se os campos foram preenchidos com dados válidos e se o método HTTP também é válido. Ao final do seguinte código também há uma chamada ao stripslashes(), que filtra as barras que possam ter sido usadas em uma tentativa de inserir dados. Apenas após estas verificações o script vai para a rotina de envio de e-mail.
include("stopinjection.inc.php");
$errors=0;
$error="The following errors were found while processing your request.<ul>";
regfld('POST','field');
regfld('POST','field2');
$msg=preg_replace("/(\015\012)|(\015)|(\012)/"," ", $msg);if($field=="" || $field2=="" ){
$errors=1;
$error.="<li>You didn't fill all the fields.";
if($errors==1) echo $error;
else{
$where_form_is=
"http".($HTTP_SERVER_VARS["HTTPS"]=="on"?"s":"")."://".$SERVER_NAME.strrev(strstr(strrev($PHP_SELF),"/"));
$message="Field 1: ".$field."
Field 2: ".$field2."
";
$message = stripslashes($message);
mail(); // Use your mail() parameters here.
}
Quando você usa uma ou mais das formas descritas para proteger seu script de e-mail injection você também ajuda a Internet a ficar livre de spam. Mesmo se você nunca foi uma vítima de e-mail injection, sempre tente manter seus scripts e servidores o mais seguro possível.
|