Az SQL-befecskendezések jelentős veszélyt jelentenek a relációs adatbázis-modellekre és az azokban tárolt érzékeny információkra. Ezért elengedhetetlenül fontos a biztonsági réseket kihasználó, jogosulatlan külső hozzáférési kísérletek elleni átfogó védelem.

Mi az az SQL-befecskendezés?

Az SQL-befecskendezés egy olyan támadási típus, amely kihasználja a relációs adatbázis-rendszerek biztonsági sebezhetőségét, amelyek az SQL lekérdezési nyelvet használják a felhasználói bevitelek feldolgozásához. A támadó kihasználja azokat a felhasználói beviteleket, amelyek nem megfelelően vannak elszigetelve, és speciális karaktereket tartalmaznak, például kettős kötőjeleket, idézőjeleket vagy pontosvesszőket. Ezek a karakterek speciális funkciókat látnak el az SQL értelmező számára, és lehetővé teszik a végrehajtott parancsok külső manipulálását. Az SQL-befecskendezések gyakran kapcsolódnak olyan PHP- és ASP-alkalmazásokhoz, amelyek elavult interfészekre támaszkodnak. Sok ilyen esetben a bevitel nem megfelelően tisztított, ami elsődleges célponttá teszi a támadás számára.

A funkciókarakterek stratégiai beillesztésével egy jogosulatlan felhasználó további SQL-parancsokat vihet be és manipulálhatja az adatbázis bejegyzéseit, hogy adatokat olvasson, módosítson vagy töröljön. Súlyos esetekben a támadók akár hozzáférést is szerezhetnek a rendszer parancssorához, ami lehetővé teheti számukra, hogy teljes ellenőrzést gyakoroljanak az adatbázis-kiszolgáló felett.

SQL-befecskendezés példája, amely bemutatja, hogyan működik egy adatbázis-támadás

Mivel a sebezhető adatbázis-kiszolgálók gyorsan azonosíthatók, és az SQL-befecskendezéses támadások viszonylag könnyen végrehajthatók, ez a módszer továbbra is az egyik legszélesebb körben alkalmazott technika a kiberbűnözők körében világszerte. A támadók különböző stratégiákat alkalmaznak, kihasználva mind az újonnan felfedezett, mind a régóta fennálló biztonsági réseket az adatkezelési folyamatban részt vevő alkalmazásokban. Az SQL-befecskendezés gyakorlati működésének jobb megértése érdekében nézzünk meg két gyakori támadási módszert példaként.

1. példa: Rosszul szűrt felhasználói bevitel útján történő hozzáférés

Az adatbázis eléréséhez a felhasználóknak általában először azonosítaniuk kell magukat. Ehhez általában szkripteket használnak, amelyek egy felhasználónév és jelszó mezőt tartalmazó bejelentkezési űrlapot jelenítenek meg. A felhasználók kitöltik az űrlapot, majd a szkript ellenőrzi, hogy vannak-e egyező bejegyzések az adatbázisban. Alapértelmezés szerint az adatbázis tartalmazhat egy users nevű táblázatot, amelynek username és password oszlopai vannak. Egy tipikus webalkalmazásban az adatbázis-hozzáféréshez szükséges szkriptsorok (Python-szerű pszeudokód használatával) így nézhetnek ki:

uname = request.POST['username']
passwd = request.POST['password']
sql = "SELECT id FROM users WHERE username='" + uname + "' AND password='" + passwd + "'"
database.execute(sql)
python

A támadó most SQL-befecskendezéssel manipulálhatja a jelszó mezőt, például password' OR 1='1 beírásával, ami a következő SQL-lekérdezést eredményezi:

sql = "SELECT id FROM users WHERE username='' AND password='password' OR 1='1'"
python

Ezzel a támadó teljes hozzáférést kap az adatbázis teljes felhasználói táblájához, mivel a jelszó feltétele mindig igaznak minősül (1='1'). Ha a támadó rendszergazdaként jelentkezik be, akkor szabadon módosíthatja az adatbázis bármelyik bejegyzését. Alternatív megoldásként a felhasználónév mező is ugyanúgy manipulálható.

2. példa: Adatok kinyerése azonosító manipulációval

Az adatbázisból azonosító alapján történő információlekérés praktikus és gyakori módszer, de egyben lehetőséget is teremt az SQL-befecskendezésre. Például egy webszerver az URL-ben továbbított azonosító adat alapján tudja, hogy mely információkat kell lekérnie az adatbázisból. A megfelelő PHP szkript így néz ki:

<?php
    $mysqli = new mysqli("localhost", "username", "password", "database");
    $id = intval($_GET['id']);
    $result = $mysqli->query("SELECT * FROM table WHERE id=$id");
    while ($row = $result->fetch_assoc()) {
        echo print_r($row, true);
    }
?>
php

A várt URL a .../script.php?id=22 mintát követi. Ebben az esetben a „22” azonosítóval rendelkező táblázatbejegyzés kerül lekérésre. Ha egy jogosulatlan személynek lehetősége van manipulálni ezt az URL-t, és helyette egy .../script.php?id=22+OR+1=1 típusú kérést küld, akkor a lekérés eredményeként a táblázat összes sora lekérésre kerül:

SELECT * FROM table WHERE id=22 OR 1=1;
sql

Hogyan találják meg a bűnözők a sebezhető adatbázis-rendszereket?

Elvileg minden olyan webhely vagy webalkalmazás, amely előre elkészített lekérdezések (előre elkészített utasítások) vagy más védelmi intézkedések nélkül használ SQL-adatbázisokat, sebezhető lehet az SQL-behatolásokkal szemben. A felfedezett sebezhetőségek nem maradnak sokáig rejtve a világhálón. Valójában vannak olyan webhelyek, amelyek naprakész listákat tesznek közzé az ismert biztonsági hibákról, és még azt is elmagyarázzák, hogyan használhatják a támadók a Google keresőjét a megfelelő webprojektek megtalálásához. Ha egy webhely részletes SQL-hibajelentéseket ad vissza, a kiberbűnözők ezeket a jelentéseket felhasználhatják a potenciális sebezhetőségek azonosítására. Például egy apostrof hozzáadása egy ID paramétert tartalmazó URL végéhez máris felfedheti a gyengeséget, ahogy az alábbi példa is mutatja:

[DomainName].com/news.php?id=5’

A sebezhető webhely a következő formában küld vissza hibaüzenetet:

Query failed: You have an error in your SQL syntax…

Hasonló módszerekkel lehet kinyerni az oszlopok számát, a táblák és oszlopok nevét, az SQL verziót, vagy akár a felhasználóneveket és jelszavakat is. Ezenkívül léteznek különböző eszközök, amelyek automatizálják mind a felfedezési folyamatot, mind az SQL-befecskendezéses támadások végrehajtását.

Hogyan védheted adatbázisodat az SQL-behatolástól?

Az adatbázis-rendszer SQL-behatolási támadásainak megelőzésére számos különböző módszer alkalmazható. Az összes érintett komponenssel foglalkozni kell – a szerverrel, az egyes alkalmazásokkal és az adatbázis-kezelő rendszerrel egyaránt.

1. lépés: Az alkalmazások automatizált bemeneteinek figyelése

Külső vagy beágyazott alkalmazásokból érkező bemenetek feldolgozásakor elengedhetetlen a beküldött értékek érvényesítése és szűrése az SQL-behatolások megelőzése érdekében.

1. Adattípusok érvényesítése

Minden beviteli mezőnek meg kell felelnie a várt adattípusnak. Például, ha numerikus beviteli mezőre van szükség, egy egyszerű érvényesítés PHP-ben így nézhet ki:

if (filter_var($input, FILTER_VALIDATE_INT) === false) {
    throw new InvalidArgumentException("Invalid input");
}
php

Hasonló ellenőrzéseket kell végrehajtani a karakterláncok, dátumok vagy más speciális formátumok esetében is.

2. Szűrje ki a speciális karaktereket

A speciális karakterek biztonsági réseket okozhatnak, különösen SQL- vagy HTML-kontextusban. Biztonságos megoldás az htmlspecialchars() használni HTML-beviteli mezőkben, PDO::quote() pedig SQL-lekérdezésekben.

3. Kerülje a hibaüzenetek megjelenítését

Kerülni kell az adatbázis vagy a rendszer technikai részleteit feltáró közvetlen hibaüzeneteket. Helyette inkább egy általános üzenetet kell megjeleníteni, például:

echo "An error occurred. Please try again later.";
error_log("Unexpected error encountered. See system log for details.");
php

4. Használjon előre elkészített utasításokat

Az SQL-befecskendezések megelőzésének egyik leghatékonyabb módja az előkészített utasítások használata. Ebben a megközelítésben az SQL-parancsok és paraméterek külön-külön kerülnek elküldésre, így a rosszindulatú kódok nem futtathatók. Íme egy példa a PDO (PHP Data Objects) használatára PHP-ben:

$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindParam(':id', $user_id, PDO::PARAM_INT);
$stmt->execute();
php

Az adatbázis-kezelő rendszer automatikusan biztosítja, hogy a bevitt adatok biztonságosan kerüljenek feldolgozásra.

2. lépés: Gondoskodjon a szerver átfogó védelméről

Az adatbázis-kezelő rendszer futtatására szolgáló szerver biztonsága szintén döntő szerepet játszik az SQL-behatolás megelőzésében. A legfontosabb intézkedés az operációs rendszer megerősítése a következő bevált gyakorlatok követésével:

  • Csak azokat az alkalmazásokat és szolgáltatásokat telepítse vagy engedélyezze, amelyek elengedhetetlenek az adatbázis futtatásához.
  • Távolítson el minden felesleges vagy nem használt felhasználói fiókot.
  • Győződjön meg arról, hogy minden releváns rendszer- és szoftverfrissítés azonnal telepítésre kerül.
  • Alkalmazzon minimális jogosultsági elvet, hogy a felhasználók és szolgáltatások csak a szükséges minimális jogosultságokat kapják meg.

A webprojekt biztonsági követelményeitől függően érdemes további védelmi intézkedéseket fontolóra venni:

  • Behatolásérzékelő rendszerek (IDS) és behatolásmegelőző rendszerek (IPS): Ezek a rendszerek különböző érzékelési módszerekkel korán felismerik a támadásokat, riasztásokat adnak ki, és – IPS használata esetén – automatikusan megkezdik az ellenintézkedéseket.
  • Alkalmazásréteg-átjáró (ALG): Az ALG közvetlenül az alkalmazás szintjén figyeli és szűri az alkalmazások és a webböngészők közötti forgalmat.
  • Webalkalmazás-tűzfal (WAF): A WAF kifejezetten védi a webalkalmazásokat az SQL-befecskendezés és a cross-site scripting (XSS) ellen azáltal, hogy blokkolja vagy megtisztítja a gyanús kéréseket.
  • Zero Trust megközelítés: Ez a modern biztonsági modell biztosítja, hogy minden hozzáférési kísérletet – függetlenül annak eredetétől – ellenőrizzenek és hitelesítsenek, mielőtt hozzáférést biztosítanak.
  • Tűzfal szabályok és hálózati szegmentálás: Ezek elengedhetetlenek a támadási felület hosszú távú minimalizálásához.
  • Rendszeres IT-biztonsági auditok és behatolási tesztek: Ezek segítenek a sebezhetőségek korai felismerésében és kijavításában.

3. lépés: Az adatbázis megerősítése és biztonságos kód használata

Az operációs rendszerhez hasonlóan az adatbázisból is el kell távolítani az összes felesleges komponenst, és naprakészen kell tartani. Távolítsa el az összes felesleges tárolt eljárást, és tiltsa le az összes fel nem használt szolgáltatást és felhasználói fiókot. Hozzon létre egy kizárólag webes hozzáférésre szánt dedikált adatbázis-fiókot, és csak a minimálisan szükséges jogosultságokat rendelje hozzá.

Az előkészített utasítások használatával összhangban erősen ajánlott, hogy ne használja a mysql PHP modult (amelyet a PHP 7-ben eltávolítottak). Ehelyett válassza mysqli vagy a PDO-t a jobb biztonság és kompatibilitás érdekében. Egy biztonságos mysqli lekérdezés így nézhet ki:

$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_error) die("Connection failed");
$stmt = $mysqli->prepare("SELECT password FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$stmt->bind_result($hashedPassword);
if ($stmt->fetch() && password_verify($_POST['password'], $hashedPassword)) {
    echo "Login successful";
} else {
    echo "Invalid login credentials";
}
$stmt->close();
$mysqli->close();
php

A jelszavakat soha nem szabad közvetlenül adatbázisban tárolni vagy egyszerű szövegként lekérdezni. Ehelyett használjon hash-módszert, például password_hash() password_verify() kombinálva, hogy biztonságosan védje a hitelesítő adatokat. Egy biztonságos megvalósítás így nézhet ki:

$mysqli = new mysqli("localhost", "username", "password", "database");
$stmt = $mysqli->prepare("SELECT password FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if ($row && password_verify($_POST['password'], $row['password'])) {
    echo "Login successful!";
} else {
    echo "Incorrect username or password.";
}
php

Mi köze van a bobby tábláknak az SQL-befecskendezéshez?

A bobby-tables.com weboldal egy xkcd webcomic segítségével humorosan szemlélteti a bizonytalan felhasználói bevitelek veszélyeit az adatbázisokban. A képregényben egy anya telefonhívást kap fiától (akit szeretettel Little Bobby Tables néven emlegetnek) az iskolából. A hívó fél megkérdezi, hogy fia valóban Robert'); DROP TABLE Students;-- hívják-e, mire az anya igennel válaszol. A hívás oka hamar kiderül: amikor Robertet próbálták beírni a diákadatbázisba, az egész diáklista törlődött. Az anya nem túl megértő – csak reméli, hogy az iskola tanult a hibájából, és a jövőben tisztázni fogja az adatbázisba bevitt adatokat.

A képregény világosan rávilágít arra, hogy milyen katasztrofális következményekkel járhat, ha az adatbázis-alkalmazásokban nem ellenőrzik és tisztítják megfelelően a felhasználói beviteleket.

Ugrás a főmenübe