+36 30 355 0880

0-24 Tudástár

Témakörök:



Új ügyfeleknek












Meglévő ügyfeleknek














Önmüködő honlap












Érdekességek











Találj meg minket a Google+-on

Domaint Tippek, Domain ötletek
Egyszerűen kitűnő. Végre egy szolgáltató aki nem csak kullog az igények előtt, hanem minőségi szolgáltatást teremt
Domain Regisztráció
Date published: 10/31/2012
5 / 5 stars

PHP, valamennyire biztonságosabban




Hogyan tegyük biztonságosabbá a php -ban készült weboldalunkat!

A biztonságot befolyásoló tényezőket két csoportra lehetne osztani. Egyrészt függhetnek a szerver beállításaitól, amelyek főleg a rendszergazdát érintik, másrészt függhetnek maguktól a futtatott PHP programoktól, amelyekért már a programozó a felelős. Valamennyire szétválasztható a kettő egymástól, de hiába ír a programozó majdnem tökéletes kódot, ha egyetlen kis hibát kihasználva hozzá lehet férni nem publikus tartalmakhoz is, mert nincs az Apache, illetve a PHP beállításai között korlátozva a fájlok elérhetősége. Ez persze fordítva is igaz, érdemes összhangban tartani a kettőt.

A php.ini fontosabb opciói, kapcsolói

 

A php.ini fájlt megtalálod a virtual szerveren a /conf mappában

 register_globals = Off

A klienstől különböző formában (GET, POST, cookie, stb.) érkező adatokat nem illeszti be a globális változók közé, hanem különböző tömbökön ($_SERVER, $_GET, $_POST, stb) keresztül lehet elérni őket, így nem tudják felülírni az esetleg a kódban felejtett, kezdőérték nélküli változókat. Érdemes rászokni ezeknek a használatára, hiszen ha mégis be van kapcsolva a register_globals, akkor is elérhetőek ezek a tömbök. Továbbá ez a módszer garantálja, hogy a változóidat tényleg onnan kaptad, ahonnan várod őket. Ha minden űrlapnál GET-tel küldöd el a mezőket, akkor a $_POST tömbben megjelenő változók nagy valószínűséggel valamiféle amatőr támadási próbálkozás jelei, érdemes lehet naplózni. A $_* tömbök csak a PHP újabb verzióiban érhetőek el, a régebbiekben használhatóak a $_TIPUS = $HTTP_TIPUS_VARS értékadások a program elején, melyek esetleg az auto_prepend_file opcióval automatikussá is tehetők. Ha véletlenül egy Off értékkel "megáldott" szerveren kell futtatni a nem ilyen szemlélettel írt programokat, akkor sajnos nagyon nagy munka (lenne) átírni őket, ezért ilyen esetekben nem biztos, hogy megéri.

display_errors = Off
Szüksége van arra a látogatóknak, hogy lássák a hibás PHP programok, nem elérhető adatbázis szerverek, stb. által generált hibaüzeneteket? Szerintem nincs, csak a támadókat segítik az ilyen módon kiadott információk, a becsületes látogatók számára ezek semmit sem fognak jelenteni. Éles webszerveren öngyilkosság bekapcsolni.

log_errors = On
Egyértelműen be legyen kapcsolva. Naplózzunk egy állományba, melyet aztán a tail -f logfile paranccsal lehet valós időben figyelni. Segítségével olyan hibaüzenetek is felfedezhetünk, amit esetleg a böngésző elrejtett volna előlünk, vagy a html forrásban véletlenül például a <!-- --> tagek közé került volna.

magic_quotes_gpc = Off
Az addslashes() függvény használata nélkül SQL függvényekhez történő hozzáférés biztonságosságán javít, magyarul a vezérlő karakterek elé rak egy \ jelet, ezzel megvédi az adatbázist az SQL parancsba valamiféle módon bekerülő kártékony kódoktól, amit az adatbázis szerver valószínűleg parancsként értelmezne. Rontja a teljesítményt, növeli a programozói hanyagságot, és nem minden adatbázisszerverrel működik együtt. Ráadásul gondot okoz akkor, ha nem rögtön adatbázisba tesszük az adatokat, hanem újra megjelenítjük mondjuk egy űrlapban. Ezért javasolt az adatbázisnak megfelelő escape megoldás használata: pg_escape_string(), mysql_escape_string(), sqlite_escape_string(), stb.

error_reporting = E_ALL
Logolj minden hibaüzenetet!. Az alapbeállítás majdnem ugyanez, csak a megjegyzések nélkül, amik hasznosak szoktak lenni az alapos programozók számára (változó nem beállított kezdeti értékkel, stb.).

safe_mode = On
Letiltja, korlátozza egy nagyobb adag függvény használatát és bevezet néhány biztonsági ellenőrzést az állományokkal kapcsolatban. Érdemes használni, főleg ha nem a saját programjaidat futtatod.

safe_mode_gid = Off
A safe_mode csak azokat az állományokat engedi megnyitni, amelyek felhasználó azonosítója megegyezik a PHP szkript UID-jével. Ha ezt is bekapcsolod, akkor a csoport azonosítót is ellenőrzi.

open_basedir = /var/www/
Segítségével Korlátozhatod az állomány-, és könyvtár kezelő függvényeket, ha be van állítva, akkor az itt megadott könyvtárakon kívül nem nyithat meg a PHP egyetlen fájlt, könyvtárat sem. A záró / fontos, mert ezt hasonlítja össze az értelmező az állomány abszolút nevével, és ha egyezik az eleje, akkor engedélyezi a megnyitást. A /var/www esetén ha létezik például egy /var/www2 könyvtár, akkor az is megnyitható.

disable_functions =
Elérhetetlenné teszi az itt felsorolt függvényeket, például a phpinfo(), az exec(), a mail(), stb. függvényekre érdemes használni.

max_execution_time = 30
Maximum ennyi ideig (másodperc) futhat egy szkript, de ez csak a PHP kódokra vonatkozik, egy bonyolultabb SQL lekérdezéssel 500 másodperc felé is sikerült már tornázni 30-as alapbeállítás mellett.

allow_url_fopen = Off
Felesleges, ha nem használjuk, kapcsoljuk ki, különben akár proxynak is használhatják a szervert, letöltve más tartalmakat.

error_log = syslog
A hibaüzenetek helye, melynek állománynév is megadható. Ha nincs beállítva, akkor az alapértelmezett ErrorLog-ba (ez Apache opció) mennek a hibaüzenetek.

enable_dl = Off
A PHP modulok dinamikus betöltése szkriptjeinkből. Safe mode esetén nem használható, más esetben is legyen kikapcsolva. Így elkerülhetjük, hogy olyan kiterjesztés kerüljön egy szkript alá, melyet nem akartunk engedélyezni.

file_uploads = Off
Ha egyik program sem tölt fel állományokat, akkor legyen Off, ha mégis akkor a php_admin_flag-gel engedélyezzük ott, ahol kell.

upload_tmp_dir =

Amíg nem kezelt a PHP egy feltöltött állományt, addig az ebben a könyvtárban tárolódik. Abban az esetben, ha az open_basedir be van állítva, akkor azon belül kell lennie, különben az állományt annak feltöltése után nem fogjuk tudni kezelni.

 

A hibaüzenetekről

 

Tesztelésnél, a program írásánál nagyon hasznosak, de csak a programozó számára, másokkal nem érdemes ezeket megosztani. A felhasználó felől érkező változóknál tapasztalt hibákat csak naplózni érdemes, a hiba okát, az adat ellenőrzésének részleteit lehetőleg ne küldjük ki a böngészőnek, syslog vagy egyéb naplóba írjuk. Ha a jelek mindenképpen arra utalnak, hogy valaki megpróbálja feltörni a programunkat, akkor küldjük át a klienst a főlapra, vagy egyéb módon szórakoztassuk a betörőt.

 

Kezdőérték nélküli változók

 

Ezek ellen tökéletes védelmet nyújt a register_globals opció kikapcsolása. Bekapcsolt állapotában az alábbi szkriptet elég könnyű lenne kijátszani, csupán csak a böngészőbe kellene beírni egy http://servercime/akarmi.php?auth=1 URL-t, és a jelszó ismerete nélkül hozzáférhetnénk a bizalmas adatokhoz. Ehhez persze szükséges az $auth változó nevének az ismerete, amit egy bekapcsolva hagyott display_errors opció vagy egy biztonsági mentés segítségével a támadó megtudhat.
  1. <?php  
  2.  if ($pass == "hello") {  
  3.    $auth = TRUE;  
  4.  }  
  5.  ...  
  6.   
  7.  if ($auth) {  
  8.    echo "szupertitkos információk";  
  9.  }  
  10. ?>  
A hiba megszüntethető az $auth változó kezdeti hamis értékének beállításával, illetve az első if feltételnél egy else ágban is pótolható a hiányosság.

 

Beérkező adatok ellenőrzése

 

Általános szabály az, hogy ne bízzunk meg egyetlen olyan adatban sem, ami a felhasználótól érkezik. A hidden típusú űrlap mezőn keresztül érkező adatokat se nehezebb variálni, mint a többit. A Javascript-es ellenőrzést csak a gyorsasága miatt érdemes használni, nem helyettesíti a PHP-n belüli ellenőrzéseket. Naplózzuk az olyan eseteket, amikor a beérkező változók nem normális, a programok megbuherálása nélkül előidézhetetlen kombinációjával találkozik a szkriptünk. Ha túl sokszor fordul elő a naplóban, akkor lehet, hogy mégis mi hibáztunk, és nem számtalan betörési kísérlettel van dolgunk.

is_* függvények

Arra valóak, hogy megmondják egy változó típusát. A böngészőtől érkező változók mindig 'string' típusúak, hiszen itt nem végez a PHP automatikus típusválasztást. Az is_numeric()-el lehet ellenőrizni, hogy egy karaktersorozat valóban számot tartalmaz-e.

A PHP a változók típusait automatikusan konvertálja, ha típuskonverzió nélkül kell összehasonlítanod két változót, akkor az === és társai nagy segítséget jelentenek, nem mindegy, hogy például egy SQL lekérdezés eredménye hibával tér vissza (FALSE), vagy nulla (0) rekorddal. Ha az ==-vel hasonlítod össze a lekérdezés eredményét tartalmazó változót, mindkét esetben ugyanazt fogod kapni.

htmlspecialchars()

Ha a felhasználótól érkező adatokat HTML kimenetbe ágyazva küldöd ki később a böngészőnek (pl. vendégkönyv, fórum), akkor elengedhetetlen a fenti függvény használata. Alkalmazása megvédi attól a weblapot, hogy a felhasználók HTML elemeket illesszenek be az adatok közé, melyek biztonsági kockázatok garmadáját nyitják meg.

Adatbázisfüggő escape megoldás

Ha az információk adatbázisban is tárolásra kerülnek, akkor erre is szükség lesz, különben akár egy véletlenül a szövegbe rakott aposztróf vagy idézőjel érvénytelenné teheti az SQL parancsot, illetve kárt is okozhat. Lásd fent.

.inc fájlok PHP-ben

A konfigurációs, illletve a függvényeket, inicializációs folyamatokat tartalmazó állományokat általában nem ajánlatos önmagában futtatni, ezért egy, a következőhöz hasonló ellenőrzéssel érdemes elküldeni a próbálkozó adatait a syslogba, vagy egyéb naplóállományba:
  1. <?  
  2. // Közvetlenül ezt az állományt kérte a kliens  
  3. if (__FILE__ == $_SERVER["DOCUMENT_ROOT"] . $_SERVER["PHP_SELF"]) {  
  4.   // Naplózó kód kerül ide és kilépünk  
  5.   die();  
  6. }  
  7. ?>  

 

Amikor nincs szükség a PHP-re

 

Előfordulhatnak olyan esetek is, amikor a weblap olyan információkat (is) tartalmaz, amelyek ugyan dinamikusan változnak, de csak bizonyos időközönként. A pillanatnyi értékük meghatározott időintervallumonként mindig állandó (pl. az előző napi látogatók száma). Ilyenkor felesleges mindig végrehajtani a bonyolultabbnál bonyolultabb SQL lekérdezéseket, illetve egyéb programrészeket.

A crontab-ból periodikusan meghívott wget, ami fájlba menti az adott pillanatra jellemző PHP kimenetet, ideálisabb megoldás az ilyen esetekre, mint a lap minden lehívásakor legenerálni ugyanazt a végeredményt, és a processzort is kevésbé terheli. Amennyiben a weblap csak egyes részei tartalmaznak ilyen, bizonyos ideig állandó információkat, akkor az include() illetve a require() függvényekkel érdemes beszúrni a wget-tel lementett fájlt a megfelelő helyre.

Ezek a programok ne legyenek mindenki számára elérhetőek, mert akkor még véletlenül is kitalálhatja valaki az állomány nevét, és így szkriptünk kívülről jövő változókkal is futtathatóvá válik. Ha a gépen shellel rendelkező felhasználók is vannak, akkor csak localhost-ra korlátozni a szkript elérhetőségét sem jó megoldás, inkább a jelszavas elérés használatát javasolnám .htpasswd állományok alkalmazásával, amelyekre persze nem adunk mindenkinek olvasási jogot.

$HTTP_REFERER ellenőrzés

Ez a változó tartalmazza annak a (űr)lapnak a címét, ahonnan a látogató ide került. A böngésző állítja be, de nem minden esetben. Mivel ez is a felhasználótól jön, nem érdemes nagyon megbízni benne, még akár egy egyszerű telnet klienssel, vagy valamilyen nyílt forrású böngésző átírásával is könnyen lehet hamisítani. Ettől függetlenül érdemes lehet egy plusz védelmi vonalként használni, megvizsgálni, hogy az űrlapokon keresztül beérkező adatok tényleg a mi űrlapunk kitöltésével kerültek-e hozzánk.

$HTTP_POST_FILES illetve $_FILES

Az A Study In Scarlet - Exploiting Common Vulnerabilities in PHP című alapműben van egy elgondolkodtató példa a fájl feltöltés kihasználásáról, miszerint a file típusú beviteli mező által beállított globális változókat ($name, $name_size, $name_type, $name_name) akár GET metódussal is megadhatjuk a PHP-nek. A beviteli mező name tulajdonságának megfelelő változó tartalmazza a helyi fájl nevét, ahova a PHP ideiglenesen elmentette a feltöltött állományt. Ezt GET-tel beállítva mondjuk a /etc/passwd-re nagy valószínűséggel ezt a fájlt fogja olvasni a program. Az open_basedir helyes beállításával, illetve az is_uploaded_file() függvénnyel kiszűrhetőek az ilyen próbálkozások, de a legjobban itt is a registered_globals opció alapértelmezett bekapcsolt állapotának megváltoztatásával járunk. Ajánlom mindenkinek a fenti tömbök használatát, illetve a http://hu.php.net/manual/en/features.file-upload.php címen található leírást.

 

Biztonsági mentések

 

Ha a szkripteket shellből is szerkeszted, akkor ügyelj a használt szerkesztők biztonsági mentéseire. Az akarmi.php szerkesztés előtti változatát könnyen elérheti bárki kívülről az akarmi.php.bak vagy akarmi.php~ néven (joe). Az nem megoldás, hogy a mentésekben használt kiterjesztésekre is engedélyezzük a PHP futtatását, mivel elképzelhető, hogy épp egy súlyos hibát javítottunk, de ott a régi, még hibás szkript is mindenki számára elérhetően. Ki kell kapcsolni a használt szerkesztők biztonsági mentési szolgálatását, vagy ezeket a kiterjesztéseket is elérhetetlenné kell tenni az Apache beállításával.

 

Sütik

 

Érzékeny adatok tárolására nem érdemes használni, egy webáruház esetén a vevők nagy mértékű kedvezményekben részesíthetik magukat, ha az árakat is a sütik tartalmazzák. Érdemesebb egy egyedi azonosítót generálni az időből és még valamilyen véletlen információból (IP cím, stb), majd megspékelni valamilyen hash függvénnyel, és mindezt egy SQL táblában tárolni, elsődleges kulcsként használva az így kapott azonosítót. A tábla többi attribútuma pedig logikusan a tárolandó adat legyen. Ha ez dinamikusan változik, akkor egy text típusú mezőbe (Postgresql esetén) elég sokmindent bele lehet zsúfolni egy tömb és a serialize(), illetve unserialize() függvény segítségével. Itt sem szabad elfelejteni a pg_escape_string() függvényt és testvéreit más adatbázisok esetén.

Ha találtál valami hasznosat a cikkben, nyomj egy tetszik gombot:

mennyire vagy ügyes domaines?

Kérlek írj egy köszönömöt, ha tetszett!

Csatlakozz a beszélgetéshez!

Mi ez, hova kerültem?

A domainflotta.hu honlap tudásbázisát nézed éppen. Rengeteg leírást és szoftveres segítséget adunk, amivel megnövelheted a forgalmad. Vagy épp megvalósíthatod az ötleted.




domain tárhely regisztráció



Ezeket már olvastad?



8 trükk amivel meghódítod a YouTube csúcsát

Ehhez elõször kicsit vissza kell ugranunk az idõben 2005-be, amikor is a&nbs...

Megnézte: 65410 ember
Fejléc elõhívása különbözõ levelezõben

E-mail fejlécek megjelenítése - felhasználói segédlet - Tartalomjegyzék E-mail fejl...

Megnézte: 33246 ember
Levelezés saját domain névvel - Gmailen keresztül

Ez az információ már elavult. A Google megszüntette a Gmail összek&ou...

Megnézte: 33002 ember
Mennyi idõ alatt készül el a .hu domain nevem?

A leggyakoribb eset Az új domain szabályzat szerint 4 munkanap alatt elbírálják a doma...

Megnézte: 30457 ember
A hely biztonsági tanúsítványa lejárt vagy A webhely tanúsítványa hibás.

Ez a "hibaüzenetet" a böngészõd írja ki, amikor megpróbálsz belépni a webes leve...

Megnézte: 28712 ember
Domain átirányítás = Google büntetés

 Sokan nem tudják, pedig létfontosságú:A Google bünteti a duplikált tartalmakat. Így a...

Megnézte: 24613 ember
Hogyan tudom rendezni az anyagiakat?

A rendelés díjának befizetésérõl:A rendelésed rögzítésekor küldünk e-mailben egy prof...

Megnézte: 24412 ember
Domain átirányítás

Domain nevet csak ip címre vagy dns címekre lehet irányítani. Az ip cím formátuma: 127.0.0....

Megnézte: 23844 ember
Hogyan tudom elolvasni a leveleimet?

  Böngészõ segítségével Hogyan? A következõ webcímre látogass el e...

Megnézte: 23828 ember
Hogyan tudok html kódot beilleszteni az oldalamba?

 Mire jó?Nagyon sok olyan eset van, amikor be kell illeszteni egy html kódot az oldalba. Ez...

Megnézte: 20777 ember