Email injekcijos
Jau užgraužė kantrybė tiek ilgai neatsinaujinant, taigi šiek tiek informacijos, kuri, manau niekam nepakenks
Email injekcija atsirado palyginti neseniai, prieš keletą metų. Tiesą sakant, tai tėra tik dar vienas aklo pasitikėjimo vartotojo įvedimu, pavyzdys. Jei Jūs naudojatės mail() funkcija, kurios argumentais leidžiate manipuliuoti vartotojams, jie gali siųsti laiškus per Jūsų serverį. Nieko nuostabaus.
Šiuo metu egzistuoja nemažai būdų kaip pasinaudoti email injekcija PHP skriptuose. Šio tipo pažeidimai yra tikras lobis el.pašto spameriams. Pagrindinė problema, dėlko el.pašto injekcija yra populiari, yra ta, jog programuotojai nesupranta duomenų filtravimo, prieš juos paduodant email funkcijai, svarbos.
Mail() funkcija suteikia ganėtinai neišdirbtą sąsąją siųsti el. paštui. Kaip ir dauguma PHP funkcijų, ši yra labai lanksti - leidžia siųsti beveik bet kokio tipo ir formato laišką.
Mail() funkcijos naudojimas yra labai paprastas, todėl nepatyrusiam programuotojui saugumo spragos dažniausiai nesimato. Pats paprasčiausias būdas išsiųsti laišką:
mail('to@pavyzdys.lt', 'Antraštė', 'Žinutė');
?>
Šis pavyzdys iškart tampa el.pašto injekcija, kai tik pirmąjį argumentą pakeičiame vartotojo įvedamu tekstu:
mail($_POST['email'], 'Antraštė', 'Žinutė');
?>
Tai panašu į bet kokią kitą injekciją, tačiau konkekstas skiriasi. Jei įvesime savo pašto adresą, gausime laišką panašų į šį (supaprastintas vaizdas):
Subject: Antraštė
From: nobody@medutis.com
Mano žinutė
Antraštės “kam” (To) reikšmė yra įvedama vartotojo, taigi kas nors, norėdamas išsiųsti spam žinutę iš Jūsų serverio, paprasčiausiai įves sąrašą adresų, atskirtų kableliais:
Galime įsivaizduoti, jog bus atlikta tokia komanda:
mail(’vienas@adresas.lt, antras@adresas.lt, trecias@adresas.lt’, ‘Antraštė’, ‘Žinutė’);
?>
Kiekvienas iš šių adresų gaus laišką, kadangi To antraštė suteikia galimybę siųsti keliems adresatams, atskirtiems kableliais. Taip pat klaidingai galvojama, jog ši problema egzistuoja tik leidžiant vartotojui operuoti pirmuoju argumentu, o nieko blogo nenutiks, jei To reikšmė bus statinė. Daug didesnių bėdų bus, jei bent dalis vartotojo įvedimo bus naudojama ketvirtajame argumente.
Headerių injekcija
Dažnai mail funkcija naudojama siųsti kontaktams ar atsiliepimams tiesiai iš puslapyje esančios formos. Jei nenurodome specialių headerių, siuntėjo adresas nustatomas web serverio. Dažniausiai formoje vartotojas nurodo savo el. pašto adresą, taigi jei norime imituoti, jog laiškas buvo siųstas būtent iš įvesto adreso, turime nurodyti headerius “From” ketvirtajame argumente.
mail(’to@pavyzdys.lt’, ‘Antraštė’, ‘Žinutė’, ‘From: medutis@medutis.com’);
?>
Aišku, tai, kad galima nurodyti laiško antraštes, mums suteikia papildomo lankstumo, tačiau čia taip pat slypi ir dideli pavojai. Įsivaizduokime tokia komandą:
mail(’to@pavyzdys.lt’, ‘Antraštė’, ‘Žinutė’, ‘From: {$_POST['email']}’);
?>
Ši komanda veiks, taip kaip ir tikitės: laiškas bus išsiųstas, o formoje įvestas email bus nurodytas kaip siuntėjo. Deja, dabar vartotojas turi visišką laisvę operuoti su antraštėmis. Vartotojas, turintis piktų kėslų, į formos ‘email’ laukelį įves:
To: medutis@medutis.com
Be abejo, šis bandymas pakenkti bus pastebėtas, kadangi to@pavyzdys.lt gaus laišką:
Subject: Antraštė
From: nuo@pavyzdys.lt
To: medutis@medutis.com
Žinutė
Laiškas bus išsiųstas abiems adresatams, tačiau, kad ši saugumo spranga nebūtų pastebėta, blogiukai pasinaudos BCC antrašte ir galės nepastebimai naudotis serveriu ilgą laiką. Įvedame:
Bcc: medutis@medutis.com
Kaip žinia, BCC antraštė nėra rodoma el. laiške, todėl to@pavyzdys.lt matys laišką, kuris tarsi buvo siųstas tik jam. Deja, pasirodys, kad neaišku kiek dar žmonių gavo tą patį laišką, todėl greitai jūsų skriptas taps spamerių numylėtiniu.
Saugumo tikrinimas
Norėdami patikrinti savo skriptus, galite įvesti daugiau nei vieną eilutę į formos įvedimo laukelį. Pavyzdžiui:
Bcc: mano@pastas.lt
Tikri spameriai naudojasi tam tikrais įrankiais, kurie automatiškai prisijungia prie web serverio ir papostina url-užkoduotus tekstus. Pavyzdžiui:
$fp = fsockopen(’www.pavyzdys.lt’, 80);
fputs($fp, “POST /webmail.php HTTP/1.1\r\n”);
fputs($fp, “Host: pavyzdys.lt\r\n”);
fputs($fp, “Content-Type: application/x-www-form-urlencoded\r\n”);
fputs($fp, “Content-Length: 95\r\n\r\n”);
fputs($fp, “email=nuo%40pavyzdys.lt%0D%0ABCC%3A+medutis%40medutis.com&subject=Mano+antraste&message=Mano+zinute”);
fclose($fp);
?>
Web serveriui POST kintamieji paduodami panašiai kaip ir GET, šiuo atveju buvo paimti entities naujai eilutei, kuri pažymėta kaip %0D%0A. Šis pavyzdys yra labai paprastas, dažnai būna vykdomos atakos siųsti HTML laiškus, prisegtus failus ir pan. Jei spameriui leidžiama operuoti funkcijos argumentais, jis gali padaryti bet ką, ką leidžia mail() funkcija.
Kaip apsisaugoti?
Tam tereikia filtruoti vartotojo įvedamus duomenis. Žinoma, uždrausti įvedinėti tarpus ar eilutės perkėlimus pačiame žinutės tekste ar jos pavadinime nereikia. Kai kuriuos email adresus išfiltruoti taip pat sudėtinga dėl jo ne itin griežtos specifikacijos. Atpažinti įvedamiems el. pašto adresams gali padėti reguliariosios išraiškos (regexp), taip išvengiant email injekcijos atakos.
$svarus_emailas = false;
$email_pattern = ‘/^[^@\s<&>]+@([-a-z0-9]+\.)+([a-z]{2,}$/i’;
if (preg_match($email_pattern, $_POST['email'])) $svarus_emailas = true;
?>
Taip pat greitas ir patogus būdas patikrinti ar kintamajame nėra perkėlimų ar naujų eilučių:
if (ctype_print($_POST['email'])) // viskas gerai!
?>
Funkcija checkdnsrr() taip pat gali padėti, jei su regexp išraiška galime išgauti domeno vardą. Tuomet su šia funkcija patikriname ar tikrai toks domenas egzistuoja. Deja, checkdnsrr() neveikia windows aplinkoje.
Paprasta apsauga nuo email injekcijų leidžia išvengti atakų, ten kur mažiausiai tikitės - dažniausiai pasitaikančiose nedidelėse kontaktų ar atsiliepimų formose. Šios formelės ypač populiarios mūsuose, taigi verta į tai atkreipti dėmesį.
June 2nd, 2006 at 11:58 am
dar nenusibodo apie php saugumą rašyti? .)
June 16th, 2006 at 9:23 am
Saugumo niekad nebus perdaug
June 28th, 2006 at 8:32 pm
butent
July 13th, 2006 at 10:40 am
Puikus straipsnis
April 24th, 2007 at 4:21 pm
Aciu…..geri straipsniai..
June 13th, 2007 at 4:05 pm
floodas
June 13th, 2007 at 4:05 pm
floodas floodas
June 13th, 2007 at 4:06 pm
floodas floodas floodas floodas