mysql_real_escape_string szükségessége

PHP mysql_real_escape_string szükségessége

Amennyiben van egy PHP-vel készített weboldalunk, amely adatbázis segítségével, tárol adatokat, vagy épp abban keresünk adatokat, szinte elkerülhetetlen, hogy a weboldal látogató ne kerüljön ezáltal kapcsolatba adatbázis lekérdezéssel. A leggyakoribb ilyen lehetőség a felhasználó azonosítása, keresés a webáruházba, vagy csak egy egyszerű listázási oldal, amely elemzése során kiderül, hogy paramétereken keresztül befolyásolhatjuk a lekérdezést, megjelenést.

SQL injection – adatbázis lekérdezésen alapuló sebezhetőség

Azt a folyamatot, támadást, mikor például a weboldalon fent felsorolt funkcionalitásán keresztül igyekszik egy látogató “hibás” bemenő adatok felhasználásával olyan lekérdezéseket végrehajtani az adatbázisban, amely segítségével rongálhatja, hibára késztetheti, hibás, érzékeny adatok visszaadására kényszeríti az adatbázist nevezzük SQL injection-nek.

Ennek a lehetőségnek az elkerülése közös érdek, hisz az internetes weboldalak jelentős része osztott tárhely szolgáltatáson működik, így a feltört oldalakon, adatbázisokon keresztül a kiszolgáló webszerver biztonságát, így más weblapok sértetlenségét is veszélyeztetjük.

PHP és a mysql_real_escape_string

PHP-ben készített weboldal esetén a mysql_real_escape_string függvény elvégzi azt az előszűrést, ami szükséges ahhoz, hogy a látogatók felől érkező minden bemenő adatból kiszűri az SQL injection támadást kiváltó paraméter részeket.

Annyit kell tennünk, hogy a bejövő adatokat ezen PHP függvény segítségével ellenőrzünk.

Pár egyszerű példa az SQL injection megoldásra, és a mysql_real_escape_string megoldásra

Feltételezzük, hogy a weboldalunkon adatbázisból azonosítunk felhasználókat. A felhasználói felületen bekérjük két input mezőn keresztül a felhasználó nevét és jelszavát. Majd ennek a kettőnek a segítségével lekérdezzük a felhasználói adatait. (Az itt leírt megoldás, igaz működik, de a biztonságos megoldástól messze van, kerülendő az ilyen lekérdezés!)

$sql = "SELECT * FROM users WHERE username='" .$_REQUEST["loginnev"]. "' AND userpasswd='" .$_REQUEST["password"]. "' AND userenable='1';

Tehát közvetlenül betesszük a lekérdezésbe a látogató felől érkező adatokat. Ez normál működés esetén az elvárt eredményt adja, tehát a lekérdezésünk helyes lesz:

SELECT * FROM users WHERE username='pistike' AND userpasswd='pistike1' AND userenable='1';

Tehát pistike felhasználó pistike1 jelszóvel be tud lépni, mert engedélyezett felhasználó.

Lássuk mi történik a lekérdezésünkkel, ha valaki SQL injection kísérel meg. Példának okáért admin felhasználót ad meg, és “‘ or ‘1’=’1′ — ‘” jelszót használ.

SELECT * FROM users WHERE username='admin' AND userpasswd='' or '1'='1' -- '' AND userenable='1';

Az 1=1 feltétel következtében a lekérdezésünk helyes lesz, függetlenül minden egyéb paramétertől. Persze lehet, hogy épp nincs admin felhasználó, de belátható, hogy mivel már csak az adminisztrátor jogosultságú felhasználó nevét kell eltalálnunk, jelentősen növekedett az oldal megtöréséhez az esélye a látogatónak. Ha ezzel együtt valaki már látta, hogy adminisztrátorként milyen felhasználóval léptünk be az oldalra, esetleg a weboldal kiírja, hogy épp az adminisztrátor felhasználó van bent, akkor gyakorlatilag kész a weboldal hack.

Mi történik, ha ekkor a felhasználói név és a jelszó esetén is használjuk a mysql_real_escape_string() függvényt?

Ez a megoldás megakadályozza az SQL injection kód bekerülését. Ez a függvény meghívja a MySQL library-ját, amely escape-eli , backslash karakterrel egészíti az paramétereket az adatbázis szerver felé elküldés előtt, pl.: \x00, \n, \r, \, ‘, ” és \x1a adatokat.

Tehát helyesen használjuk így a bejövő adatokat, mielőtt az adatbázis szerver felé küldjük:

$sql = "SELECT * FROM users WHERE username='" .mysql_real_escape_string($_REQUEST["loginnev"]). "' 
AND userpasswd='" .mysql_real_escape_string($_REQUEST["password"]). "' AND userenable='1';

Arra most nem térnék ki, csak egy rövid megjegyzéssel, hogy például ilyen esetben, mikor jelszó ellenőrzés, tárolás történik az adatbázisban, akkor az soha ne legyen “plain text”, tehát olvasható módon tárolva.

Comments are closed, but trackbacks and pingbacks are open.