Aktuális helyzet: PHP2Shell. Két kritikus PHP-rés (CVSS 9,2) lehetővé teszi kártékony kód futtatását bejelentkezés nélkül. Javítások 2026. 10. 21. óta.Mi a teendő most →

PHP és adatbázisok: PDO és mysqli

A PHP a PDO-n vagy a mysqli-n keresztül szólítja meg az adatbázisokat. Itt látja a különbségeket, a prepared statementekkel végzett biztonságos lekérdezéseket, és mit kell tenni az adatbázis-hozzáférésekkel egy szerverincidens után.

Állapot 5 perc olvasási időPHP-tudástár

Röviden: A PHP két elterjedt felületen keresztül fér hozzá az adatbázisokhoz: a PDO (PHP Data Objects) sok adatbázis-rendszerrel dolgozik egységes felületen, a mysqli a MySQL-re és a MariaDB-re van szabva. Mindkettővel a prepared statementek, vagyis a helyőrzős lekérdezések megbízhatóan védenek az SQL-injekció ellen. A PHP 8.0 (PDO), illetve 8.1 (mysqli) óta mindkettő alapértelmezetten kivételként jelzi a hibákat.

Hogyan beszél a PHP az adatbázisokkal

Szinte minden PHP-alkalmazás adatbázisban tárolja a tartalmait: oldalakat, rendeléseket, felhasználói fiókokat, beállításokat. A PHP-szkript ehhez kapcsolatot létesít, SQL nyelven lekérdezést küld, és feldolgozza az eredményt. A hozzáférési adatok többnyire egy konfigurációs fájlban állnak ugyanazon a szerveren.

Az ügyvezetés számára ez azért fontos, mert az adatbázis többnyire a vállalkozás legértékesebb adatait tartalmazza. Aki a webszerveren kódot tud végrehajtani, az általában a konfigurációs fájlt is el tudja olvasni, és ezekkel a hozzáférési adatokkal hozzáférhet az adatbázishoz.

PDO és mysqli összehasonlítva

Jellemző PDO mysqli
Adatbázisok sok, olyan illesztőprogramokon keresztül, mint a PDO_MYSQL, PDO_PGSQL, PDO_SQLITE, PDO_SQLSRV, PDO_OCI MySQL és MariaDB
Helyőrzők elnevezett (:name) és pozicionális (?) pozicionális (?)
Stílus objektumorientált objektumorientált és procedurális
Hiba kivételként alapértelmezett a PHP 8.0.0 óta alapértelmezett a PHP 8.1.0 óta
Rövid forma paraméteres lekérdezésekhez prepare() és execute() tömbbel execute_query() a PHP 8.2.0 óta

A gyakorlatban gyakran a keretrendszer vagy a CMS dönt. Sok saját adatbázisréteget hoz magával, amely belsőleg a PDO-t vagy a mysqli-t használja. Aki átvesz egy alkalmazást, a forráskódban végzett egyszerű kereséssel megállapíthatja, melyik felületet használják, és hol keletkeznek lekérdezések:

# Hol létesít kapcsolatot az alkalmazás, hol keletkeznek lekérdezések?
grep -rn --include='*.php' -E 'new PDO|new mysqli|mysqli_connect|->query\(' /var/www/app/src | head -50

A ->query( találatok nem automatikusan veszélyesek. Megérdemelnek azonban egy második pillantást, mert ott az értékek közvetlenül az SQL-szövegbe kerülhetnek, ahelyett, hogy helyőrzőkön keresztül adnák át őket. Éppen a régebbi projektek keverik a két stílust, és az ellenőrzés minden nagyobb frissítés előtt megéri.

Prepared statementek: a legfontosabb minta

Prepared statementnél a lekérdezést helyőrzőkkel küldik az adatbázisnak, az értékeket pedig külön adják át. A PHP-kézikönyv szerint ez véd az SQL-injekció ellen, ha minden felhasználói bevitel helyőrzőkön keresztül halad.

<?php
declare(strict_types=1);

$pdo = new PDO(
    'mysql:host=localhost;dbname=shop;charset=utf8mb4',
    $dbUser,
    $dbPass,
    [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
);

$stmt = $pdo->prepare('SELECT id, name FROM kunden WHERE plz = :plz AND aktiv = :aktiv');
$stmt->execute(['plz' => $plz, 'aktiv' => 1]);

foreach ($stmt as $zeile) {
    echo htmlspecialchars($zeile['name'], ENT_QUOTES, 'UTF-8'), "\n";
}

Ugyanez a mysqli-vel a PHP 8.2 óta létező rövid formában:

<?php
$db = new mysqli('localhost', $dbUser, $dbPass, 'shop');
$ergebnis = $db->execute_query('SELECT id, name FROM kunden WHERE plz = ?', [$plz]);

foreach ($ergebnis as $zeile) {
    echo htmlspecialchars($zeile['name'], ENT_QUOTES, 'UTF-8'), "\n";
}

A fejlesztőknek két korlátot kell ismerniük. A helyőrzők nem állhatnak idézőjelek között; LIKE keresésnél a % helyettesítő karakterek az átadott értékbe tartoznak. És a helyőrzők csak értékeket helyettesítenek, tábla- vagy oszlopneveket nem. Hogy az ilyen különleges eseteket hogyan lehet biztonságosan megoldani, azt az SQL-injekció megelőzése PHP-ban útmutató mutatja.

Hibakezelés: kivételek néma hibák helyett

Korábban mindkét felület alapértelmezetten némán dolgozott: egy sikertelen lekérdezés false értéket adott, és aki ezt nem ellenőrizte, üres adatokkal dolgozott tovább. Ez megváltozott:

  • PDO: A PHP 8.0.0 óta a PDO::ERRMODE_EXCEPTION az alapértelmezett. A hibák PDOException kivételt dobnak.
  • mysqli: A PHP 8.1.0 óta a hibajelzés a MYSQLI_REPORT_ERROR és a MYSQLI_REPORT_STRICT értékre van állítva. A hibák mysqli_sql_exception kivételt dobnak; korábban a jelzés ki volt kapcsolva.

A biztonság szempontjából ez azt jelenti: a kivételeket el kell kapni és naplózni kell, de soha nem szabad SQL-szöveggel, táblanevekkel vagy hozzáférési adatokkal a böngészőben végezniük. Hogyan lehet ezt tisztán szétválasztani, azt a Hibák és kivételek a PHP-ban oldal írja le.

Hozzáférési adatok és jogok helyes kiosztása

Az adatbázis csak annyira védett, mint a hozzáférési adatai. Ezek a szabályok váltak be:

  1. Alkalmazásonként külön felhasználó: Soha ne használja az adatbázis adminisztrátorát a weboldalhoz.
  2. Csak a szükséges jogok: Egy weboldalnak többnyire olvasásra, írásra, módosításra és törlésre van szüksége a saját adatbázisában, más adatbázisokra vagy szerverfunkciókra vonatkozó jogokra viszont nincs.
  3. Ok nélkül ne legyen távoli kapcsolat: Az adatbázisnak csak a webszerverről szabad elérhetőnek lennie, az internetről nem.
  4. A hozzáférési adatok a webgyökéren kívül: A konfigurációs és .env fájlok nem lehetnek URL-en keresztül lekérhetők. Erről bővebben a A hozzáférési adatok és a .env fájlok védelme cikkben.
  5. Titkosított kapcsolat szétválasztott szervereknél: Ha az adatbázis másik gépen van, a kapcsolatnak titkosítottan kell futnia, hogy a hozzáférési adatok és a tartalmak ne haladjanak nyílt szövegként a hálózaton.
  6. Külön hozzáférések a karbantartáshoz: Az adatmentés, a kiértékelések és az adminisztrátorok saját felhasználót kapnak. Így a naplóból nyomon követhető, ki mit tett, és egy hozzáférés a weboldal zavarása nélkül zárolható.

Adatbázisok, PHP2Shell és az éles eset

A PHP2Shell nem magát az adatbázist érinti, hanem a PHP-értelmezőt: a CVE-2026-109618 és a CVE-2026-109619 bejelentkezés nélkül lehetővé teszi kártékony kód végrehajtását. Ha ez sikerül, a kód a PHP-folyamat jogaival fut, és így általában el tudja olvasni az adatbázis hozzáférési adatait tartalmazó konfigurációs fájlt. A prepared statementek ez ellen nem segítenek, mert a támadás egyáltalán nem SQL-lekérdezésen keresztül zajlik.

Kötelező ezért a PHP 8.5.12, 8.4.27, 8.3.36 vagy 8.2.35 verzióra való frissítés és az összes PHP-folyamat újraindítása. Ha vannak jelek sikeres támadásra, új adatbázis-hozzáférési adatok, az adatbázis ellenőrzése beinjektált tartalmak szempontjából, és a GDPR szerinti bejelentési kötelezettség értékelése is hozzátartozik. Itt egy strukturált Incident Response értelmes.

Tipp

Az adatbázisjelszavakat csak a szerver megtisztítása után változtassa meg. Amíg kártékony kód fut, az az új hozzáférési adatokat is újra ki tudja olvasni.

Hogyan segít konkrétan a PHP SOS?

  • Ellenőrizzük, hogyan fér hozzá az alkalmazása az adatbázishoz, és hogy a felhasználók, a jogok és a hálózati hozzáférés megfelelnek-e a minimumnak.
  • Ellenőrizzük, hogy a konfigurációs és hozzáférési fájlok a webgyökéren kívül vannak-e, és nem érhetők-e el nyilvánosan.
  • Incidens után a megfelelő sorrendben megújítjuk a hozzáférési adatokat, és megvizsgáljuk az adatbázist beinjektált kód szempontjából.
  • Az eredményeket úgy dokumentáljuk, hogy az adatvédelmi felelősök és a biztosítók nyomon követhessék.

Gyakori kérdések

PDO-t vagy mysqli-t használjak?

Új projektekhez a PDO többnyire a rugalmasabb választás, mert sok adatbázissal dolgozik ugyanazon a felületen. A mysqli akkor értelmes, ha kizárólag MySQL-t vagy MariaDB-t használ, és szüksége van azok különleges funkcióira. Mindkettő biztonságos, ha a prepared statementeket következetesen használják.

A PDO hiba esetén automatikusan kivételt dob?

Igen, a PHP 8.0.0 óta a PDO::ERRMODE_EXCEPTION az alapértelmezett. Korábban a néma mód volt az, amelyben a hibák csak az errorCode() és az errorInfo() útján voltak lekérdezhetők. A régebbi alkalmazások a módot gyakran még kifejezetten beállítják.

A helyőrzők helyettesíthetnek tábla- vagy oszlopneveket is?

Nem. A helyőrzők csak értékeket helyettesítenek. A tábla- és oszlopneveket, például egy rendezéshez, ellenőrizni kell az engedélyezett nevek rögzített listájával, mielőtt behelyettesítik őket a lekérdezésbe.

A PHP2Shell után meg kell változtatnom az adatbázis jelszavát?

Pusztán a frissítés ezt nem követeli meg. Ha viszont vannak jelek arra, hogy a szerver kompromittálódott, a konfigurációs fájlokban lévő összes hozzáférési adat ismertnek tekintendő. Ilyenkor a takarítás után újítsa meg őket.

Források

Azonnali kapcsolat

Minden óra számít. Írjon nekünk most.

Ismertesse röviden a rendszert, a PHP-verziót és a megfigyelését. Jelentkezünk, tisztázzuk a helyzetet, és távolról dolgozunk, amíg az incidens le nem zárul és dokumentálva nem lesz.

Azonnali segítség