Trust, de ellenőrizze az sql-injekciók elleni védelmet - datalife motor (dle)
Bizalom, de ellenőrizze: az SQL injekciók elleni védelem
Kétségtelen, hogy az SQL injekciók az egyik leggyakoribb módszer a webhely hackelésére. Az első dolog, amit a cracker megpróbál tenni, a népszerű injekciók tesztelése. Ebben a rövid bejegyzésben röviden áttekinteni a történelem a kérdés, módszerekkel foglalkozó injekciókat, és írj egy kis PHP-osztály egy wrapper a PDOStatement biztonságos kommunikációt, és befolyásolja a MySQL-szerver (MySQL ebben az esetben egyszerűen azért, mert a legnagyobb előfordulási, ha azt szeretnénk, az összes alábbi más DBMS-ekhez igazítható).
Mi lényegében az injekció? Egy kezdõs php-developer, aki most kezdte el tanulmányozni a MySQL-t, nagy valószínűséggel lekérdezéseket fog létrehozni a következõ módon:
Jó felhasználó esetén a szkript pontosan úgy működik, ahogyan azt tervezték. Mit fog tenni a támadó? Nem küld számszerű értéket a kiszolgálónak. Ehelyett megpróbálja, hogy egy számérték után pontosvessző (szimbólum SQL-lekérdezés teljes), majd írni a saját, így nem kell az eredetileg fogant kérésünket. Valami ilyesmi:
vagy még rosszabb:
Ennek eredményeként, a MySQL-szerver először elvégzi a vizsgálatot, és a háta mögött - a támadó kérését. Így a támadó, a helyzettől függően (és jogait MySQL felhasználó, aki a PHP), hogy szinte semmit, ne férjen hozzá a bizalmas információkat a teljes ellenőrzést az adatbázis.
Hogyan védi a fejlesztő a webhelyét az injekcióktól?
A felhasználói adatok kézi ellenőrzése. Természetesen az input formátum ellenőrzése az injekciók elleni védelem első legnyilvánvalóbb formája. Ahelyett, hogy megbíznánk a beviteli adatokkal, ellenőrizzük, hogy megfelelnek-e a szükséges formátumnak. Ezt tíz különböző módon teheti meg. Például:
Ebben az esetben a GET-ből érkező információk ellenőrzése számszerű értékre történik a küldés előtt. A támadó által megadott numerikus értéktől eltérő értékeket nem fogják elküldeni a MySQL kiszolgálónak. Bonyolultabb értékek validálásához szabályos kifejezéseket használhat.
A primitív védelem egy másik változata a mysqli_real string_escape () natív függvény használata, amely megakadályozza a "sérült" kérelmek behatolását. Ennek a megközelítésnek a legfőbb hátránya az extrém nonautomáció: a felhasználói értéket mindig ellenőrizni kell, amikor kérést teszünk. Természetesen használhatsz egy kész SQL-készítőt, beépített védelemmel az SQL injekciók ellen, vagy írhatod a sajátját. Azonban ebben a bejegyzésben az OEM használatán alapuló enyhén eltérő megközelítést kínálunk.
Az 5.1-es verziótól kezdve a PHP beépített OEM-osztályú (PHP Data Objects). Ez az osztály gazdag módszert kínál számos adatbázis kezeléséhez. Annak ellenére, hogy az előrehaladott kor az eszköz sok fejlesztő nem veszi figyelembe, inkább a „régi vágású” használni a könyvtárat a mysqli, beleértve minket a DLE, de van számos fontos okból a DLE egy régi script megjelent sokáig a OEM és van egy elkötelezettség a kompatibilitást a régi változat a forgatókönyvet, valamint a maximális egyszerűsítésére a frissítési folyamat, azok számára, akik a harmadik féltől származó modulokkal. Ráadásul nagyon óvatosan közelítünk a bejövő adatok szűréséhez. De veled ellentétben nem vagyunk annyira régi „dinoszauruszok”, így a fő gondolata akarunk közvetíteni, hogy ez: a közvetlen felhasználásra mysqli nélkül csomagolóanyagok - direkt módon ezt az SQL-injection, így írni kódot egyszer biztos. A fejlesztőknek valójában csak három kimenetük van:
- használja a felhasználói adatok manuális ellenőrzését
- Írja be saját könyvtárát (vagy vegye be) a mysqli alapján SQL injektálással
- használja az OEM-t
A mi osztályunk csak 4 módszert fog tartalmazni:
- az adatbázishoz való csatlakozás módja
- a kapcsolat ellenőrzésének módja
- módszer a biztonságos kérelem küldésére a PDOStatementen keresztül
- módszer az adatbázis-kapcsolat megszakításához
Az első 5 tartalmazza a gazdagépet, az adatbázis nevét, a bejelentkezést, a jelszót és a kódolást, és nincs magyarázat. A 6. tulajdonságban hasznos az objektum pdo tárolása. Az első lépés természetesen az összekapcsoláshoz szükséges módszer írása:
Az első sor a kiszolgálóhoz való csatlakozás paramétereit tartalmazza. A $ connopt tömb meghatározza az OEM-vel való együttműködés különböző módjait. Ezek a módok használhatók a hibák és a speciális helyzetek finomhangolására. Nem fogunk beleavatkozni a kézikönyvben használt opciók részleteibe. Az érdeklődők a PHP-re vonatkozó részletesebb dokumentációra hivatkozhatnak. Itt megjegyezzük, hogy az utolsó sorban olyan objektumot hozunk létre, amely az OEM-vel dolgozik, átadva a megadott paramétereket a tervezőnek, és ezt az objektumot $ pdo tulajdonságunkba írjuk.
Tehát csatlakozunk az alaphoz. Írjuk ugyanazt a módszert, ha ellenőrizzük a kapcsolatot. Ennek érdekében a getAttribute (PDO :: ATTR_CONNECTION_STATUS) metódust használjuk. Normál kapcsolat esetén a "hostname via TCP / IP" karakterláncot adja vissza, ahol a gazdanév a host neve.
Ha a pdo tulajdonság üres, akkor a kapcsolat nem jön létre (vagy megsemmisült). A következő lépés, hogy ellenőrizze a getAttribute visszatérési értékét, és hasonlítsa össze a normál értékkel. Ha más, dobja hamisnak. Ha minden rendben ment, akkor igaz legyen. Ha nem, hamis.
Most, valójában a legérdekesebb. Írjunk egy módszert biztonságos kérés elküldésére az adatbázisba.
A módszerünk három argumentummal fog rendelkezni:
- a kérelem testülete
- asszociatív tömböt egy sor értékekkel
- Egy bináris argumentum, amely meghatározza, hogy visszaadja-e az adatokat az adatbázisból. A SELECT'ov végrehajtásához ez az argumentum igaz lesz, és INSERT'ov \ UPDATE'ov - false esetén.
Lássuk, mi történik itt. Az első feltétel akkor szükséges, ha lekérdezés végrehajtására csak akkor kerül sor, ha van kapcsolat az adatbázishoz. A második feltétellel ellenőrizzük az értékek sorát (helyőrzőket). Ha a tömb nincs megadva, akkor a lekérdezést "ahogy van" végrehajtjuk. Ha a helyőrzők tömbje létezik, argumentumként továbbítjuk a execute () metódushoz. A módszerek előkészítik () és végrehajtják () - és van valami, amihez mindent létrehoztak. Amint azt észrevetted, amikor az OEM-rel az adatbázis segítségével dolgozol, a kérelem szervezet és értékei külön-külön kerülnek továbbításra. Ebben az esetben a kérelmet a következő formában kell feltüntetni:
Ahol: user_id a végrehajtott () végrehajtott tömb kulcsa. Vagyis a PDOStatement használatával kifejezetten egy kérelmet küldenek:
Egy kapcsolat elpusztításához csak adj egy nullot a pdo objektumhoz. Ezért a kapcsolat kiküszöbölésének módja a legrövidebb lesz:
Ezért összerakjuk az osztályunkat: