Biztonságosabb PHP
A legtöbb internetes oldalon lehetősége van a felhasználónak adatokat küldeni a szerver felé, amiket nekünk programozóknak meg kell tisztítanunk az olyan részektől, melyek kárt tehetnek a rendszerben. A PHP 5.2.0 óta rendelkezésünkre áll az adatszűrés, angolul data filtering. Ebben a cikkben ezt nézzük át részletesebben.
Miért tisztítsunk és érvényesítünk?
Amikor a felhasználó adatot küld, akkor meg kell bizonyosodnunk róla, hogy az adat tartalmaz -e olyan részeket, mely ártalmas lehet az oldalunkra nézve. Az ilyen adatokat nem validnak, azaz nem érvényes adatnak nevezzük, és én 4 formáját emelném ki:
- Cross-Site Scripting (XSS): Ennek a módszernek a segítségével általában javascript kódokat illesztenek be oldalunkba, ami nagyon szét tudja csapni az oldalunkat. Bővebben itt olvashattok róla.
- SQL Injection: A második legnépszerűbb módszer, ahol úgy hajtanak végre plusz utasítást a rossz akarók, hogy közben az eredeti is lefut, így nehezen lehet észrevenni, hogy valami nem stimmel. Bővebben itt.
- Cross-Site Request Forgery (CSRF/XSRF): Egy kevesebbet használt technika, mely például képek src tulajdonságát megváltoztatva scripteket futtat le anélkül, hogy a felhasználó ennek tudatában lenne. Bővebben itt.
- Helytelen adat: Ez igazából nem feltétlenül rossz indulatú input, viszont szétzilálhatja oldalunk, ha telefonszámokhoz, vagy pénz összegekhez betűket is engedünk beírni.
Ebben a cikkben csak a szerver oldali biztonságról fogok írni, de a problémát a felhasználói oldalról is meg lehet közelíteni azáltal, hogy eleve nem engedünk bizonyos adatokat beírni, vagy elküldeni a szerver felé.
Hogy még az elején jobb rálátásunk legyen az érvényesítés és tisztítás közti különbségekre, a PHP manual a következőt írja róla:
A validáció az adat érvényességét ellenőrzni, hogy megfelel -e bizonyos kritériumoknak. Például a FILTER_VALIDATE_EMAIL szűrő eldönti hogy az adat érvényes email cím -e, viszont ha nem akkor nem változtat rajta.
A tisztítás /angolul sanitization ami higénikussá tételt jelent/ megtisztítja az adatot a nem oda illő részektől. Például a FILTER_SANITIZE_EMAIL eltüntetni az inputból azokat a karaktereket, amelyeket egy email cím nem tartalmazhat, viszont nem validálja azt. Tehát ha az input 67developer@gma!#il@com, akkor a ennek eredménye a 67developer@gmail@com lesz, ami tiltott karaktert ugyan nem tartalmaz, viszont nem is érvényes email cím.
Milyen szűrők állnak rendelkezésedre?
Nem minden PHP lehet azonos módon beállítva szűrők szempontjából, ugyanis a PHP 5.2.0 óta használnak szűrőket, amik egy külön kiegészítőben találhatóak meg. A legtöbb esetben minden szűrőt tartalmaz a szerverre telepített PHP, de jobb biztosra menni, ezért itt találhattok egy kódot, ami kilistázza az elérhető szűrőket:
Szűrők használata
A PHP szűrő és tisztító filter_var függvényét két paraméterrel kell meghívni. A következő példában egy változót megtisztítunk úgy, hogy a benne található egész számokat szeretnénk megtartani:
A kimenet pedig a következő lesz:
Amint látható, az első paraméterben magát az adatot, a másodikban pedig a tisztítás módját adtuk meg, majd végeredményként csak számokat tartalmazó kimenetet kaptunk.
Szűrők fajtái
Ez a lista ugyan nem teljes, de a legfontosabb szűrőket megtalálhatjuk benne.
FILTER_VALIDATE_BOOLEAN: Leellenőrzi, hogy a kapott adat logikai érték -e. Lehetséges értékeiIgazat:
- TRUE-val tér vissza ha az adat “1″, “true”, “on”, “yes”
- FALSE ha az adat “0″, “false”, “off”, “no”
- Egyébként NULL a visszatérési érték
$value01 = "on"; if(filter_var($value01,FILTER_VALIDATE_BOOLEAN)) { echo 'TRUE'; } else { echo 'FALSE'; } echo ' '; $value02 = "no"; if(filter_var($value02,FILTER_VALIDATE_BOOLEAN)) { echo 'TRUE'; } else { echo 'FALSE'; }
FILTER_VALIDATE_EMAIL: Ellenőrzi, hogy az adat érvényes e-mail cím -e. Azt nem ellenőrzi, hogy a cím létezik-e, csak a formáját. Első esetben igazat, másodikban hamisat kapunk, hisz hiányzik az email cím vége.
$value01 = 'test@example.com'; if(filter_var($value01,FILTER_VALIDATE_EMAIL)) { echo 'TRUE'; } else { echo 'FALSE'; } echo ' ' $value02 = 'nettuts'; if(filter_var($value02,FILTER_VALIDATE_EMAIL)) { echo 'TRUE'; } else { echo 'FALSE'; }
FILTER_VALIDATE_FLOAT: Ellenőrzi, hogy az adat lebegőpontos szám -e. Első esetben igaz, másodikban hamis értéket kapunk, mivel a lebegőpontos számot ponttal és nem vesszővel kell leírni.
$value01 = '1.234'; if(filter_var($value01,FILTER_VALIDATE_FLOAT)) { echo 'TRUE'; } else { echo 'FALSE'; } echo ' ' $value02 = '1,234'; if(filter_var($value02,FILTER_VALIDATE_FLOAT)) { echo 'TRUE'; } else { echo 'FALSE'; }
FILTER_VALIDATE_INT: Az előzőhöz hasonlóan ellenőrzi, hogy az adat egész szám -e. Első esetben igaz, másodikban hamis értéket kapunk.
$value01 = '123456'; if(filter_var($value01,FILTER_VALIDATE_INT)) { echo 'TRUE'; } else { echo 'FALSE'; } echo ' ' $value02 = '123.456'; if(filter_var($value02,FILTER_VALIDATE_INT)) { echo 'TRUE'; } else { echo 'FALSE'; }
FILTER_VALIDATE_URL: Ellenőrzi, hogy érvényes e az url cím, azonban azt nem ellenőrzi, hogy valóban létezik -e az oldal ahova mutat.
$value01 = 'http://net.tutsplus.com'; if(filter_var($value01,FILTER_VALIDATE_URL)) { echo 'TRUE'; } else { echo 'FALSE'; } echo ' ' $value02 = 'nettuts'; if(filter_var($value02,FILTER_VALIDATE_URL)) { echo 'TRUE'; } else { echo 'FALSE'; }
FILTER_SANITIZE_STRING: Megtisztítja az adatot olyan részektől, melyek nem érvényesek vagy nem megengedettek. Ilyen például a HTML kód <script> vagy <strong>.
$value = '<script type="text/javascript"><!--mce:0--></script>'; echo filter_var($value, FILTER_SANITIZE_STRING);
Az eredmény pedig:
alert('TROUBLE HERE');
FILTER_SANITIZE_ENCODED: Ez ugyanazt a feladatot látja el, mint az url kezelésre használt urlencode() függvény, ami többek között a space és speciális karakterek helyett a kódolt formályukat adja vissza.
$value = '<script type="text/javascript"><!--mce:1--></script>'; echo filter_var($value, FILTER_SANITIZE_ENCODED);
Az eredmény:
%3Cscript%3Ealert%28%27TROUBLE%20HERE%27%29%3B%3C%2Fscript%3E
FILTER_SANITIZE_NUMBER_INT: Megtisztítja az adatot minden olyan karaktertől ami nem int, azaz szám típusú.
$value01 = '123abc456def'; echo filter_var($value01, FILTER_SANITIZE_NUMBER_INT); echo ''; $value02 = '1.2.3.4.5.6.7.8.9'; echo filter_var($value02, FILTER_SANITIZE_NUMBER_INT);
Eredmény:
123456 123456789
Összegzés
Nagyon hasznos függvények, érdemes velük megismerkedni jobban. Aki többre kívánics, az utánaolvashat a http://www.php.net/manual/en/book.filter.php oldalon.






THX Sokat segített
Végre egy hasznos oldal.