Tehát úgy gondolja, hogy az SQL adatbázis hatékony és biztonságos az azonnali megsemmisüléstől? Nos, az SQL Injection nem ért egyet!


Igen, azonnali pusztításról beszélünk, mert nem akarom ezt a cikket a „biztonság szigorítása” és a „rosszindulatú hozzáférés megakadályozása” szokásos béna terminológiájával megnyitni. Az SQL befecskendezés olyan régi trükk a könyvben, hogy mindenki, minden fejlesztő, nagyon jól ismeri róla, és jól tudja, hogyan lehet ezt megakadályozni. Kivéve ezt a furcsát, amikor csúsznak, és az eredmények semmi esetre sem katasztrofálisak.

Ha már tudja, mi az SQL befecskendezés, nyugodtan ugorjon a cikk második felére. De azok számára, akik csak most lépnek fel a webfejlesztés területén és álmodoznak idősebb szerepek betöltéséről, néhány bevezetés megfelelő.

Mi az SQL befecskendezés??

Az SQL Injection megértésének kulcsa a neve: SQL + Injection. A „befecskendezés” szónak itt nincs semmiféle orvosi konnotációja, inkább az „injekció” ige használata. Ez a két szó együttesen ábrázolja az SQL webes alkalmazásba helyezésének gondolatát.

SQL beillesztése egy webalkalmazásba. . . Hmmm . . Egyébként nem ez az, amit csinálunk? Igen, de nem akarjuk, hogy a támadó vezesse az adatbázisunkat. Megértjük ezt egy példa segítségével.

Tegyük fel, hogy tipikus PHP webhelyet épít egy helyi e-kereskedelmi áruház számára, ezért úgy dönt, hogy hozzáad egy ilyen kapcsolatfelvételi űrlapot:

A neved

Az üzeneted

Tegyük fel, hogy a send_message.php fájl mindent tárol egy adatbázisban, hogy az üzlettulajdonosok később elolvashassák a felhasználói üzeneteket. Lehet, hogy van valamilyen kódja:

<?php

$ name = $ _POST [‘név’];
$ üzenet = $ _POST [‘üzenet’];

// ellenőrizze, hogy a felhasználónak van-e üzenete
mysqli_query ($ conn, "VÁLASZT * az üzenetek közül, ahol név = $ név");

// Egyéb kód itt

Tehát először megpróbálja megtudni, hogy ennek a felhasználónak már van olvasatlan üzenete. A SELECT * lekérdezés az üzenetekből, amelyekben a név = $ név elég egyszerűnek tűnik, igaz?

ROSSZ!

Ártatlanságunkban az ajtókat nyitottuk adatbázisunk azonnali megsemmisítésére. Ahhoz, hogy ez megtörténjen, a támadónak a következő feltételeknek kell teljesülnie:

  • Az alkalmazás SQL adatbázisban fut (manapság szinte minden alkalmazás)
  • A jelenlegi adatbázis-kapcsolat „szerkesztési” és „törlési” engedélyekkel rendelkezik az adatbázisban
  • A fontos táblák nevei kitalálhatók

A harmadik pont azt jelenti, hogy most, hogy a támadó tudja, hogy e-kereskedelemmel foglalkozik, nagy valószínűséggel a megrendelés adatait a megrendelési táblázatban tárolja. Mindez fegyveres, a támadónak csak ezt kell tennie, mint nevét:

Joe; csonka parancsok? Igen Uram! Lássuk, mi lesz a lekérdezés, ha azt végrehajtja a PHP szkript:

SELECT * FROM üzenetek közül, ahol név = Joe; csonka parancsok;

Oké, a lekérdezés első részében szintaxishiba van (nincs idézet a „Joe” körül), de az pontosvessző kényszeríti a MySQL motort, hogy kezdjen egy új értelmezését: csonkolja a parancsokat. Ugyanúgy, egyetlen mozdulattal a teljes rendelési előzmények eltűntek!

Most, hogy tudta, hogyan működik az SQL Injection, ideje megvizsgálni, hogyan állíthatja le azt. A sikeres SQL-befecskendezéshez szükséges két feltétel:

  1. A PHP szkriptnek módosítania / törölnie kell az adatbázis jogosultságait. Úgy gondolom, hogy ez igaz minden alkalmazásra, és nem fogja tudni, hogy alkalmazásai csak olvashatóvá váljanak. És gondold ki, még akkor is, ha eltávolítunk minden módosító jogosultságot, az SQL befecskendezés továbbra is lehetővé teheti valakinek SELECT lekérdezések futtatását és az összes adatbázis, az érzékeny adatok megnézését. Más szavakkal, az adatbázis-hozzáférési szint csökkentése nem működik, és az alkalmazásának egyébként szüksége van rá.
  2. A felhasználói adatok feldolgozása folyamatban van. Az SQL injekció csak akkor működhet, ha adatokat fogad el a felhasználóktól. Még egyszer: nem praktikus leállítani az alkalmazás összes bemenetet, csak azért, mert aggódik az SQL befecskendezése miatt.

Az SQL befecskendezés megakadályozása a PHP-ben

Most, mivel az adatbázis-kapcsolatok, a lekérdezések és a felhasználói bevitel az élet része, hogyan lehet megakadályozni az SQL-befecskendezést? Szerencsére ez elég egyszerű, és kétféleképpen meg lehet csinálni: 1) fertőtleníteni a felhasználó által megadott adatokat, és 2) felhasználni az elkészített utasításokat.

Fertőtlenítse a felhasználói bemeneteket

Ha régebbi PHP-verziót használ (5.5 vagy annál alacsonyabb, és ez nagyon megtörténik a megosztott tárhelyen), bölcs dolog az összes felhasználói bemenetet a mysql_real_escape_string () nevű függvényen futtatni. Alapvetően az, amit eltávolít, eltávolítja a karakterlánc összes speciális karakterét, így elveszítik a jelentését, amikor az adatbázis használja.

Például, ha olyan karakterlánccal rendelkezik, mint amilyenek vagyok egy karakterlánc, akkor a támadó a (‘) egy idézőjelet felhasználhatja a létrehozott adatbázis-lekérdezés manipulálására és SQL injekció létrehozására. A mysql_real_escape_string () keresztül történő futtatásával karakterláncot kapok, amely háttérszínt ad az egyetlen idézethez, elkerülve azt. Ennek eredményeként az egész karakterláncot ártalmatlan karakterláncként továbbítják az adatbázisba, ahelyett, hogy részt vehetnek a lekérdezés manipulációjában.

Ennek a megközelítésnek van egy hátránya: ez egy igazán, nagyon régi technika, amely a PHP adatbázis-hozzáférésének régebbi formáival együtt jár. A PHP 7-től kezdve ez a funkció még nem létezik, ami a következő megoldáshoz vezet.

Használjon elkészített állításokat

Az elkészített utasítások az adatbázis-lekérdezések biztonságosabb és megbízhatóbb elkészítésének egyik módja. Az ötlet az, hogy a nyers lekérdezés adatbázisba küldése helyett először megmondjuk az adatbázisnak az elküldött lekérdezés szerkezetét. Erre gondolunk egy nyilatkozat „elkészítése” alatt. Miután egy nyilatkozatot elkészítettünk, átadjuk az információkat parametrizált bemenetekként, hogy az adatbázis „kitöltse a hiányosságokat” azáltal, hogy bemeneti adatokkal bekapcsolja a korábban elküldött lekérdezési struktúrát. Ez elveszíti a bemenetek esetleges különleges energiáját, és arra vezet, hogy azokat pusztán változóként (vagy ha hasznos terhelésként) kezelik a teljes folyamat során. Így néz ki az elkészített nyilatkozatok:

<?php
$ kiszolgálónév = "helyi kiszolgáló";
$ felhasználónév = "felhasználónév";
$ jelszó = "Jelszó";
$ dbname = "mydb";

// Kapcsolat létrehozása
$ conn = new mysqli ($ kiszolgálónév, $ felhasználónév, $ jelszó, $ dbname);

// Ellenőrizze a kapcsolatot
if ($ conn->connect_error) {
meghal("Kapcsolat nem sikerült: " . $ conn->connect_error);
}

// előkészítés és kötés
$ stmt = $ conn->készít("INSERT INTO MyGuests (keresztnév, vezetéknév, e-mail) ÉRTÉKEK (?,?,?)");
$ stmt->bind_param ("sss", $ keresztnév, $ vezetéknév, $ e-mail);

// paraméterek beállítása és végrehajtás
$ keresztnév = "János";
$ vezetéknév = "Dámvadtehén";
$ email = "[Email protected]";
$ stmt->végre ();

$ keresztnév = "Mary";
$ vezetéknév = "Moe";
$ email = "[Email protected]";
$ stmt->végre ();

$ keresztnév = "Julie";
$ vezetéknév = "Dooley";
$ email = "[Email protected]";
$ stmt->végre ();

visszhang "Új rekordok létrehozása sikeres";

$ stmt->Bezárás();
$ conn->Bezárás();
?>

Tudom, hogy a folyamat szükségtelenül bonyolultnak hangzik, ha még nem ismeri az elõkészített nyilatkozatokat, de a koncepció megéri az erõfeszítést. Íme egy szép bevezetés.

Azok számára, akik már ismerik a PHP OEM OEM kiterjesztését és használják azt elkészített nyilatkozatok létrehozására, van egy kis tanácsom.

Figyelem: Legyen óvatos az OEM beállításakor

Ha OEM-t használunk az adatbázis-hozzáféréshez, akkor belemerülhet a hamis biztonsági érzésbe. „Ó, nos, az OEM-t használom. Most nem kell másra gondolnom ”- így gondolkodásmódunk általában így megy. Igaz, hogy az OEM (vagy a MySQLi által készített nyilatkozatok) elegendő mindenféle SQL-befecskendezési támadás megakadályozásához, de a beállításkor óvatosnak kell lennie. Gyakori, hogy csak az oktatóanyagokból vagy a korábbi projektekből másolja be a kódot, és lépjen tovább, de ez a beállítás mindent visszavonhat:

$ dbConnection->setAttribute (OEM: ATTR_EMULATE_PREPARES, igaz);

Ez a beállítás azt jelenti, hogy az OEM elõírja az elkészített utasítások emulálását, ahelyett, hogy az adatbázis elõkészített utasításai funkcióját használja. Következésképpen a PHP egyszerű lekérdezési karakterláncokat küld az adatbázishoz, még akkor is, ha a kódja úgy néz ki, mintha előkészített utasításokat hozna létre és beállítja a paramétereket. Más szavakkal, ugyanolyan sebezhető vagy az SQL injekcióval szemben, mint korábban. ��

A megoldás egyszerű: ellenőrizze, hogy ez az emuláció hamis-e.

$ dbConnection->setAttribute (OEM: ATTR_EMULATE_PREPARES, hamis);

Most a PHP szkript kénytelen az előkészített utasításokat felhasználni adatbázis szinten, megakadályozva mindenféle SQL befecskendezést.

A WAF használatának megakadályozása

Tudja, hogy a WAF (webes alkalmazások tűzfala) segítségével megóvhatja a webes alkalmazásokat az SQL-befecskendezéstől is?

Nos, nem csak az SQL-befecskendezés, hanem sok más réteg 7. sebezhetősége, például a webhelyek közötti szkriptek, megszakadt hitelesítés, a webhelyek közötti hamisítás, az adatok expozíciója, stb. Használhatja önkiszolgálóként, például a Mod Security vagy a felhőalapú, az alábbiak szerint:.

SQL injektálás és modern PHP keretrendszer

Az SQL injekció annyira általános, olyan egyszerű, annyira frusztráló és annyira veszélyes, hogy az összes modern PHP webes keret beépített ellenintézkedésekkel jár. Például a WordPress-ben megvan a $ wpdb->készítsd el a () függvényt, míg ha MVC keretet használsz, akkor minden piszkos munkát végez az Ön számára, és nem is kell gondolkodnia az SQL befecskendezés megakadályozásáról. Kicsit idegesítő, hogy a WordPress-ben kifejezetten el kell készítenie a kijelentéseket, de hé, ez a WordPress, amiről beszélünk. ��

Mindenesetre, véleményem az, hogy a webfejlesztők modern fajtájának nem kell az SQL-injektálásra gondolkodnia, és ennek eredményeként még nem is tudják a lehetőséget. Mint ilyen, még ha egy hátsó ajtót nyitva is hagynak az alkalmazásukban (valószínűleg ez egy $ _GET lekérdezési paraméter és a régi szokások, amikor egy piszkos lekérdezés bekapcsolják), az eredmények katasztrofálisak lehetnek. Tehát mindig jobb, ha időt vesz igénybe, hogy mélyebben belemerüljön az alapokba.

Következtetés

Az SQL Injection nagyon csúnya támadás egy webes alkalmazás ellen, de könnyen elkerülhető. Amint azt a cikkből láttuk, a felhasználó bemeneteinek feldolgozásakor óvatosan kell eljárni (egyébként az SQL Injection nem az egyetlen fenyegetés, amelyet a felhasználói bemenetek kezelése okoz), és az adatbázis lekérdezéséhez is tartozik. Ennek ellenére nem mindig dolgozunk egy webes keretrendszer biztonságán, ezért jobb, ha tisztában vagyunk az ilyen típusú támadásokkal, és nem esünk bele..

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me