Bezpieczne e-maile w PHP

W kodzie PHP e-mail z poprzedniego rozdziału znajduje się lukę.

PHP E-mail Iniekcja

Po pierwsze, spojrzyj na kod PHP z poprzedniego rozdziału:

<html>
<body>
<?php
if (isset($_REQUEST['email']))
//Jeśli pole "email" jest wypełnione, wysyłaj e-mail
  {
  //Wysyłaj e-mail
  $email = $_REQUEST['email'] ; 
  $subject = $_REQUEST['subject'] ;
  $message = $_REQUEST['message'] ;
  mail("someone@example.com", "Temat: $subject",
  $message, "From: $email" );
  echo "Dziękujemy za użycie naszego formularza e-mail";
  }
else
//Jeśli pole "email" nie jest wypełnione, wyświetl formularz
  {
  echo "<form method='post' action='mailform.php'>
  E-mail: <input name='email' type='text' /><br />
  Temat: <input name='subject' type='text' /><br />
  Wiadomość:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>
</body>
</html>

Problemem powyższego kodu jest to, że użytkownicy bez uprawnień mogą wprowadzać dane do nagłówka e-maila za pomocą formularza.

Co się stanie, jeśli użytkownik doda te teksty do pola input w formularzu?

someone@example.com%0ACc:person2@example.com
%0ABcc:person3@example.com,person3@example.com,
anotherperson4@example.com,person5@example.com
%0ABTo:person6@example.com

Jak zwykle, funkcja mail() umieszcza powyższy tekst w nagłówku e-maila, więc teraz nagłówek ma dodatkowe pola Cc:, Bcc: oraz To:. Kiedy użytkownik kliknie przycisk wysyłania, e-mail zostanie wysłany do wszystkich podanych adresów!

PHP zapobieganie wstrzyknięciom e-mail

Najlepszym sposobem zapobiegania wstrzyknięciom e-mail jest weryfikacja wprowadzenia.

Poniższy kod jest podobny do poprzedniego, ale dodaliśmy program weryfikacji wprowadzenia pola e-mail w formularzu:

<html>
<body>
<?php
function spamcheck($field)
  {
  //filter_var() sanitizes the e-mail 
  //address using FILTER_SANITIZE_EMAIL
  $field=filter_var($field, FILTER_SANITIZE_EMAIL);
  //filter_var() validates the e-mail
  //address using FILTER_VALIDATE_EMAIL
  if(filter_var($field, FILTER_VALIDATE_EMAIL))
    {
    return TRUE;
    }
  else
    {
    return FALSE;
    }
  }
if (isset($_REQUEST['email']))
  //if "email" is filled out, proceed
  //check if the email address is invalid
  $mailcheck = spamcheck($_REQUEST['email']);
  if ($mailcheck==FALSE)
    {
    echo "Invalid input";
    }
  else
    //send email
    $email = $_REQUEST['email'] ; 
    $subject = $_REQUEST['subject'] ;
    $message = $_REQUEST['message'] ;
    mail("someone@example.com", "Temat: $subject",
    $message, "From: $email" );
    echo "Dziękujemy za użycie naszego formularza e-mail";
    }
  }
else
  {//jeśli "email" nie jest wypełniony, wyświetl formularz
  echo "<form method='post' action='mailform.php'>
  E-mail: <input name='email' type='text' /><br />
  Temat: <input name='subject' type='text' /><br />
  Wiadomość:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>
</body>
</html>

W powyższym kodzie użyliśmy PHP filtrów do walidacji wejścia:

  • FILTER_SANITIZE_EMAIL usuwa nielegalne znaki e-maila ze ciągu znaków
  • FILTER_VALIDATE_EMAIL weryfikuje adres e-mail

Możesz znaleźć nas Filtrowanie PHPWięcej informacji na temat filtrów można znaleźć w tym rozdziale.