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
Ez az utolsó módszerről szól, és beszélni fog. Az OEM-nek van egy speciális módszere, a PDOStatement néven. Lényege abban rejlik, hogy maga a lekérdezés és az oszlopok vagy lekérdezési paraméterek értékei külön-külön átadásra kerülnek a MySQL kiszolgálónak. Így minden esetben beépített védelmet nyújtunk az injekciózás ellen (nos, vagy csaknem mindent). Annak a ténynek köszönhetően, hogy a PDOStatement meglehetősen nehézkes (a kódsorok szempontjából), akkor a legalkalmasabb, ha önhordó csomagolást használunk, amit most írunk. Ahhoz, hogy azonnal hozzászokjanak a jóhoz, tevékenységeik eredményeit formális formában formalizáljuk.

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
Szóval induljunk el. Az adatbázis használatához 6 tulajdonságra van szükségünk:

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.
Tehát a módszerünk:

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: