Wysyłanie maili w PHP
Często chcemy, aby użytkownik miał możliwość polecenia naszej strony znajomemu. Wtedy udostępniamy na stronie prosty skrypt. Prosta implementacja zostanie przedstawiona i wyjaśniona poniżej.
Niestety takie skrypty często zawierają błędy, które umożliwiają spamerowi rozesłanie wielu kopii różnych wiadomości, nawet zmieniając treść, którą chcemy przekazać. W dalszej części artykułu pokażę, jak zabezpieczyć skrypt przed niektórymi problemami.
Prosty skrypt wysyłający e-mail w PHP
Do wysłania maila możemy posłużyć się wbudowaną w PHP funkcją mail. Skrypt jest bardzo prosty, a funkcja mail łatwa w wykorzystaniu we własnym skrypcie. Wykorzystanie funkcji mail może być różne, ja w moim skrypcie używam 4 parametrów do przekazania odpowiednio adresu e-mail, tytułu, wiadomośći, dodatkowego nagłówka FROM.
![]()
if($_POST['to']!='' && $_POST['from']!=''){
$msg = 'Przykladowy mail od '.$_POST['from'];
if(mail($_POST['to'],'Test',$msg,'From: '.$_POST['from'])){
echo 'Wysłano e-mail;';
}else{
echo 'Nieoczekiwany błąd';
}
}else{
echo 'Musisz podac swoj mail i mail znajomego.<br>';
}
![]()
![]()
do tego wystarczy prosty formularz, coś w tym stylu:
<form action="skrypt.php" method="POST">
Do:<input type="textbox" name="to"><br>
Od:<input type="textbox" name="from"><br>
<input type="submit" value="Poleć">
</form>
Co w tym skrypcie jest nie tak?
Wydawać by się mogło, że taki prosty skrypt jest bezpieczny, lecz nic bardziej mylnego. Umożliwia on wysłanie maili do wielu ludzi jednocześnie. W jaki sposób o tym przekonamy się zaraz.
Dlaczego jednak powinniśmy martwić się tym, że ktoś wykorzysta nasz skrypt do rozsyłania spamu? Po prostu, administrator może usunąć nasze konto jeśli uzna nas za spamerów.
Listę błędów rozpocznie najprostszy problem, czyli wysyłanie maili do wielu osób jednocześnie. Jak łatwo to zrobić? Wystarczy w polu "to" formularze podać kilka adresów pooddzielanych przecinkami. Serwer SMTP automatycznie roześle kopie wiadomości do każdej skrzynki. Jak temu zapobiec? Można wprowadzić rozsądne ograniczenie na długość pola w formularzu, jednak ktoś może odpowiednio ominąć to zabezpieczenie. Więc pozostaje wykrycie tego przypadku w skrypcie.
![]()
if(ereg("[,]+", $_POST['to'])!==false){
$error = true;
}
if($_POST['to']!='' && $_POST['from']!='' && !$error){
$msg = 'Przykladowy mail od '.$_POST['from'];
if(mail($_POST['to'],'Test',$msg,'From: '.$_POST['from'])){
echo 'Wysłano e-mail;';
}else{
echo 'Nieoczekiwany błąd';
}
}else{
echo 'Musisz podac swoj mail i mail znajomego.<br>';
}
![]()
![]()
Skrypt ten zapewnie już, że nie zostanie wysłana już większa liczba wiadomości. Nic bardziej mylnego, skrypt jest nadal niezabezpieczony. Wystarczy spróbować zmienić nagłówek e-maila. Można to zrobić na kilka sposobów. Przedewszystkim upewnijmy się, że nie ma znaku nowej linii w żadnej zmiennej, co uniemożliwi napastnikowi przekazania kilku nagłówków. Na dodatek sprawdzimy czy ktoś nie przekazuje w żadnej zmiennej nagłówka Content-type (tak dla pewności), gdyż umożliwia on zmiane treści na przykład w naszym skrypcie.
Jak może wyglądać przykładowy atak? Może on wyglądać na przykład na przekazaniu do skryptu PHP takiego ciągu:
Content-Type: multipart/mixed; boundary="===============1999958368=="
MIME-Version: 1.0
Subject: 9c954098
To: victim@domain.com
bcc: victim@domain2.com
From: somebody@domain.com
![]()
--===============1999958368==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
![]()
Wiadomosc od spamera
--===============1999958368==
Jesli coś takiego trafi do naszego skryptu spamer przekaże wiadomość (choć pojawią sie pewne śmieci). Część z tych nagłówków jest nie potrzebna, a niektóre można zmienić (jak np. kodowanie). Zabezpieczmy przed tym nasz skrypt:
![]()
if(ereg("[,n]+", $_POST['to'])!==false){
$error = true;
}
if(ereg("[,n]+", $_POST['from'])!==false || stristr($_POST['from'],'Content-type')!==false){
$error = true;
}
if($_POST['to']!='' && $_POST['from']!='' && !$error){
$msg = 'Przykladowy mail od '.$_POST['from'];
if(mail($_POST['to'],'Test',$msg,'From: '.$_POST['from'])){
echo 'Wysłano e-mail;';
}else{
echo 'Nieoczekiwany błąd';
}
}else{
echo 'Musisz podac swoj mail i mail znajomego.<br>';
}
![]()
![]()
Ten kod jest zabezpieczony lepiej, choć i w nim mogą znaleźć się dziury. Dochodzi jeszcze możliwość floodingu. Można tu użyć ciasteczek, ale ciasteczka łatwo można skasować lub zignorować odpowiednim skryptem. Najlepiej więc użyc do tego bazy danych przechowując numery IP i date dodania. W ten sposób możemy zablokować na 5 min. dostęp do skryptu danemu userowi. Oczywiście istnieje zagrożenie, że będzie zmieniał nr IP, ale to jest już znacznie trudniejsze.
Jednak tematyka anty-floodingu to temat na obszerny artykuł, dlatego nie zostanie tutaj on poruszony. Mimo to, mam nadzieje, że ten artykuł okaże się przydatny i uchroni kilku webmasterów przed usunięciem konta przez administratora.










