Skip navigation

Videólecke

SQL befecskendezések

Az SQL befecskendezések a felhasználói felületen keresztül megadott SQL utasítások vagy olyan karaktersorozatok, amelyek a beírt adatokat feldolgozó SQL utasításokkal adatmegjelenítést vagy kárt (pl. adatvesztést) okoznak. Ezek a támadások a figyelmetlenül vagy hanyagul kezelt adatfeldolgozást használják ki. A következőkben a leggyakoribb SQL befecskendezéseket tárgyaljuk példákon keresztül. Ezek a támadások általában a webes felületű rendszereket érik. A példáinkban is azt fogjuk feltételezni, hogy valamilyen webes felületű alkalmazásunk van, amely rendelkezik egy vagy több beviteli mezővel, amely lehetőséget biztosít a támadásra. A példáinkat kellően általánosan fogalmazzuk meg, nem szögezünk le semmilyen programozási nyelvet.

Példák SQL befecskendezésekre

Táblák keresése

Ha a támadó az adatbázis tábláira vonatkozóan szeretne információhoz jutni, akkor szintén használhatja a felhasználói felületet. Ezeknek a támadásoknak a célja ténylegesen egy konkrét tábla (például a felhasználók táblának) létezésének kiderítése.

Tegyük fel, hogy van egy beviteli mezőnk amely egy terméknevet vár és azt dolgozza fel egy lekérdezésben. Az adatfeldolgozó kódrészet:

kapott_sztring = sztring_a_beviteli_mezobol ();
eredmeny = sql_execute (" SELECT * FROM termek WHERE termeknev =’" +  kapott_sztring + "’");

Írjuk a beviteli mezőbe a következő karaktersorozatot:

1' OR 0 < (SELECT COUNT(*) FROM <keresett táblanév>) OR ''='

A <keresett táblanév> helyére beírjuk azt a táblát, amelynek létezésére kíváncsiak vagyunk. Ha létezik a tábla, akkor érvényes lesz az utasítás, és vagy kapunk vissza eredményrekordot vagy nem, de ha nincs ilyen tábla, akkor hibaüzenet jön létre (amely vagy le van kezelve vagy nincs). Az is előfordulhat, – bár nem valószínű, – hogy a keresett tábla üres.

Az ilyen kereséseket szintén a karaterek átlakításával, karakterkódjukra cseréjével tudjuk kivédeni.

Kötegelt SQL utasítások

A kötegelt SQL utasítások olyan SQL utasítások, amelyeket egymás után adnak meg. Az ilyen támadások szintén a beviteli mezőkön keresztül zajlanak és szintén a behelyettesítést használják ki. A támadó a beviteli mezőbe „lezárja” az előző utasítást és egy kártékony utasítást ír mögé, kötegelve.

A kötegelt SQL utasítások kivédése a legtöbb adatbázis-kezelő rendszerben már ki van védve, nem lehet kötegelt utasításokat futtatni. A támadás megelőzésére ellenőrizhetjük és átalakíthatjuk az inputot, valamint használhatunk megbízható függvénykönyvtárakat az adatbázis-kezelésre, amely tartalmazza az SQL utasítások előkészítését és a külső értékek ellenőrzött bekötését az utasításba.

Adatbázis feltérképezése

A fenti videóleckében is látunk példát arra, hogy hogyan lehet bizonyos információkat kinyerni. A sérülékenység részben abból ered ebben az esetben, hogy a programozó rendszergazdaként csatlakozik az adatbázishoz. Korlátozott jogosultságú felhasználóként ilyen lekérdezésekre nem lenne lehetősége.

Adatbázisok listázása:

SELECT schema_name FROM information_schema.schemata;

Táblák listázása:

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema !=’mysql’ AND
table_schema!=’information_schema’;

Oszlopok listázása:

SELECT table_schema, table_name, column_name
FROM information_schema.columns
WHERE table_schema !=’mysql’ AND
table_schema!=’information_schema’;

Védekezési lehetőségek

A fentiekben számos példát láttunk SQL befecskendezésekre, láttuk, hogy a támadók ilyen SQL utasításokkal milyen adatokhoz juthatnak hozzá és milyen károkat tehet. Most foglaljuk össze, hogy programozóként, rendszerfejlesztőként milyen lépéseket tehetünk az ilyen jellegű támadások ellen!

  1. Hozzunk létre egy adatbázis-felhasználót a csatlakozáshoz és korlátozzuk a jogkörét! Rendkívül fontos lépés ez, ugyanis a legtöbb SQL injekció adminisztrátori végrehajtással működik csak. Ha mindjárt a fejlesztés kezdetekor egy külön felhasználóval érjük el az adatbázist, amely csak adatmanipulációs jogokkal rendelkezik, akkor nem tud rendszerre vonatkozó adatokat lekérdezni. Gondoljuk végig, hogy ha felhasználói szerepkörök tartoznak az adatbázisunkhoz, akkor ezeknek a szerepköröknek milyen adatbázis műveleteket szabad végrehajtaniuk. Ha lehetőségünk van, akkor minden felhasználói szerepkörhöz rendelhetünk jogkört, vagy megkülönböztethetünk egy „hagyományos felhasználót”, és egy „főnököt”, aki nagyobb jogkörrel rendelkezik. Korlátozhatjuk az adatbázis műveleteket az egyes táblákra vonatkozóan is, például egy webshop esetében a „hagyományos felhasználó” a Termékek táblából lekérdezni tud adatokat, a „főnök” viszont hozzáadhat új rekordot, módosíthatja és törölheti is a rekordokat.
  2. Ellenőrizzük a kapott adatot! Ez a második fontos védvonalunk az adatbiztonság tekintetében. Amennyiben tudjuk, hogy a beírt adat milyen karaktereket tartalmazhat, milyen hosszú lehet, ismerjük a formátumát (például dátum esetében), akkor írjunk ezekre vonatkozóan reguláris kifejezéseket és ellenőrizzük alkalmazás szinten azt, hogy beírt adat megfelel-e az elvárásoknak! Amennyiben akár formai vagy hosszbeli eltérést észlelünk, alkalmazás szinten tudunk hibajelzést küldeni a felhasználónak és az adatot nem helyettesítjük be az SQL utasításba. Ha a megadott adat minden ilyen elvárásnak megfelel és átmegy a szűrésen, akkor biztos megoldás, hogy a karaktereit lecseréljük a karakterek kódjaira. Ha így írjuk be, akkor az SQL utasítások sem utasításként hajtódnak végre, csupán karakterkódok sorozata lesz. Ily módon ártalmatlaníthatjuk az SQL befecskendezéseket.
  3. Készítsük elő az SQL utasításokat! A legtöbb programozási nyelvben és függvénykönyvtárban, amely SQL adatbázisokat kezelni tud már alapvető biztonsági eszköz az, hogy az SQL utasításokat elő lehet készíteni és a kívülről érkező paramétereket hozzá lehet kötni az utasításokhoz. Így nem sztringként fűzzük be az utasításba, hanem rábízzuk a feldolgozó függvényekre a külső adat bekötését. Ezekre a megoldásokra nem hoztunk itt példát, mert a sérülékeny, érzékeny kódrészleteket szerettük volna itt bemutatni, de további példákban megmutatjuk, hogyan kell ezeket megvalósítani PHP-ben.