Aktuálna situácia: PHP2Shell. Dve kritické zraniteľnosti PHP (CVSS 9.2) umožňujú spustenie škodlivého kódu bez prihlásenia. Záplaty od 21. 10. 2026.Čo treba urobiť teraz →

PHP a databázy: PDO a mysqli

PHP komunikuje s databázami cez PDO alebo mysqli. Tu vidíte rozdiely, bezpečné dopyty s prepared statements a čo robiť s prístupmi k databáze po incidente na serveri.

Stav 5 min čítaniaZnalosti o PHP

Stručne: PHP pristupuje k databázam cez dve rozšírené rozhrania: PDO (PHP Data Objects) pracuje s mnohými databázovými systémami cez jednotné rozhranie, mysqli je šité na MySQL a MariaDB. Pri oboch spoľahlivo chránia pred SQL injection prepared statements, teda dopyty so zástupnými znakmi. Od PHP 8.0 (PDO), resp. 8.1 (mysqli) hlásia obe chyby štandardne ako výnimku.

Ako PHP komunikuje s databázami

Takmer každá aplikácia PHP ukladá svoj obsah do databázy: stránky, objednávky, používateľské kontá, nastavenia. Skript PHP na to nadviaže spojenie, pošle dopyt v jazyku SQL a spracuje výsledok. Prístupové údaje sú väčšinou v konfiguračnom súbore na tom istom serveri.

Pre vedenie firmy je to dôležité, pretože databáza obsahuje zvyčajne najcennejšie údaje podniku. Kto môže na webovom serveri vykonať kód, môže spravidla prečítať aj konfiguračný súbor a s týmito prístupovými údajmi pristupovať k databáze.

PDO a mysqli v porovnaní

Vlastnosť PDO mysqli
Databázy mnohé, cez ovládače ako PDO_MYSQL, PDO_PGSQL, PDO_SQLITE, PDO_SQLSRV, PDO_OCI MySQL a MariaDB
Zástupné znaky pomenované (:name) a pozičné (?) pozičné (?)
Štýl objektovo orientovaný objektovo orientovaný a procedurálny
Chyby ako výnimka štandard od PHP 8.0.0 štandard od PHP 8.1.0
Skrátená forma dopytov s parametrami prepare() a execute() s poľom execute_query() od PHP 8.2.0

V praxi často rozhoduje framework alebo CMS. Mnohé prinášajú vlastnú databázovú vrstvu, ktorá interne používa PDO alebo mysqli. Kto preberá aplikáciu, môže jednoduchým hľadaním v zdrojovom kóde zistiť, ktoré rozhranie sa používa a kde dopyty vznikajú:

# Kde aplikácia nadväzuje spojenia, kde vznikajú dopyty?
grep -rn --include='*.php' -E 'new PDO|new mysqli|mysqli_connect|->query\(' /var/www/app/src | head -50

Nálezy s ->query( nie sú automaticky nebezpečné. Zaslúžia si však druhý pohľad, pretože tam sa môžu hodnoty dostať priamo do textu SQL namiesto odovzdania cez zástupné znaky. Práve staršie projekty miešajú oba štýly a kontrola sa oplatí pred každou väčšou aktualizáciou.

Prepared statements: najdôležitejší vzor

Pri prepared statement sa dopyt so zástupnými znakmi pošle databáze a hodnoty sa odovzdajú oddelene. Podľa príručky PHP to chráni pred SQL injection, ak všetky vstupy používateľa idú cez zástupné znaky.

<?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";
}

To isté s mysqli v skrátenej forme, ktorá existuje od PHP 8.2:

<?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";
}

Dve hranice by mali vývojári poznať. Zástupné znaky nesmú stáť v úvodzovkách; pri vyhľadávaní cez LIKE patria zástupné znaky % do odovzdanej hodnoty. A zástupné znaky nahrádzajú iba hodnoty, nie názvy tabuliek alebo stĺpcov. Ako takéto osobitné prípady bezpečne vyriešiť, ukazuje príručka Ako zabrániť SQL injection v PHP.

Spracovanie chýb: výnimky namiesto tichých chýb

Dávnejšie pracovali obe rozhrania štandardne potichu: zlyhaný dopyt vrátil false a kto to nekontroloval, pracoval ďalej s prázdnymi údajmi. To sa zmenilo:

  • PDO: Od PHP 8.0.0 je PDO::ERRMODE_EXCEPTION štandardom. Chyby vyhadzujú PDOException.
  • mysqli: Od PHP 8.1.0 je hlásenie chýb nastavené na MYSQLI_REPORT_ERROR a MYSQLI_REPORT_STRICT. Chyby vyhadzujú mysqli_sql_exception; predtým bolo hlásenie vypnuté.

Pre bezpečnosť to znamená: výnimky sa musia zachytávať a zaznamenávať, ale nikdy nesmú skončiť v prehliadači s textom SQL, názvami tabuliek alebo prístupovými údajmi. Ako to čisto oddeliť, opisuje stránka Chyby a výnimky v PHP.

Správne prideľovať prístupové údaje a práva

Databáza je chránená len tak dobre, ako jej prístupové údaje. Osvedčili sa tieto pravidlá:

  1. Vlastný používateľ pre každú aplikáciu: Nikdy nepoužívať administrátora databázy pre web.
  2. Len potrebné práva: Web zvyčajne potrebuje čítať, zapisovať, meniť a mazať vo svojej vlastnej databáze, ale nie práva na iné databázy alebo funkcie servera.
  3. Žiadne vzdialené spojenie bez dôvodu: Databáza by mala byť dostupná len z webového servera, nie z internetu.
  4. Prístupové údaje mimo webrootu: Konfiguračné súbory a súbory .env nesmú byť dostupné cez URL. Viac v príspevku Ochrana prístupových údajov a súborov .env.
  5. Šifrované spojenie pri oddelených serveroch: Ak databáza leží na inom počítači, spojenie by malo byť šifrované, aby prístupové údaje a obsah nešli sieťou v čitateľnej podobe.
  6. Vlastné prístupy pre údržbu: Zálohovanie, analýzy a správcovia dostanú vlastných používateľov. Tak sa dá v logu dohľadať, kto čo urobil, a prístup sa dá zablokovať bez rušenia webu.

Databázy, PHP2Shell a krízový prípad

PHP2Shell sa netýka samotnej databázy, ale interpretera PHP: CVE-2026-109618 a CVE-2026-109619 umožňujú spustenie škodlivého kódu bez prihlásenia. Ak sa to podarí, kód beží s právami procesu PHP a môže tak spravidla prečítať konfiguračný súbor s prístupovými údajmi k databáze. Prepared statements proti tomu nepomáhajú, pretože útok vôbec nejde cez dopyt SQL.

Povinná je preto aktualizácia na PHP 8.5.12, 8.4.27, 8.3.36 alebo 8.2.35 a reštart všetkých procesov PHP. Ak existujú náznaky úspešného útoku, patria k tomu nové prístupové údaje k databáze, kontrola databázy na votknutý obsah a posúdenie oznamovacej povinnosti podľa GDPR. Tu dáva zmysel štruktúrovaný Incident Response.

Tip

Heslá k databáze meňte až po vyčistení servera. Kým beží škodlivý kód, môže znova prečítať aj nové prístupové údaje.

Ako konkrétne pomáha PHP SOS?

  • Kontrolujeme, ako vaša aplikácia pristupuje k databáze a či používatelia, práva a sieťový prístup zodpovedajú minimu.
  • Overujeme, či konfiguračné súbory a súbory s prístupovými údajmi ležia mimo webrootu a nie sú verejne dostupné.
  • Po incidente obnovujeme prístupové údaje v správnom poradí a kontrolujeme databázu na votknutý kód.
  • Výsledky dokumentujeme tak, aby ich mohli sledovať zodpovední za ochranu údajov a poisťovne.

Časté otázky

Mám použiť PDO, alebo mysqli?

Pre nové projekty je PDO zvyčajne flexibilnejšou voľbou, pretože pracuje s mnohými databázami cez to isté rozhranie. mysqli dáva zmysel, ak používate výlučne MySQL alebo MariaDB a potrebujete ich špeciálne funkcie. Obe sú bezpečné, ak sa dôsledne používajú prepared statements.

Vyhadzuje PDO pri chybách automaticky výnimky?

Áno, od PHP 8.0.0 je štandardom PDO::ERRMODE_EXCEPTION. Predtým to bol tichý režim, v ktorom boli chyby dostupné len cez errorCode() a errorInfo(). Staršie aplikácie tento režim často ešte nastavujú výslovne.

Môžu zástupné znaky nahradiť aj názvy tabuliek alebo stĺpcov?

Nie. Zástupné znaky stoja len za hodnoty. Názvy tabuliek a stĺpcov, napríklad pre zoradenie, sa musia pred vložením do dopytu skontrolovať voči pevnému zoznamu povolených názvov.

Musím po PHP2Shell zmeniť heslo k databáze?

Samotná aktualizácia to nevyžaduje. Ak však existujú náznaky, že server bol kompromitovaný, všetky prístupové údaje v konfiguračných súboroch sa považujú za známe. Potom by ste ich mali po vyčistení obnoviť.

Zdroje

Okamžitý kontakt

Každá hodina sa počíta. Napíšte nám hneď.

Stručne opíšte systém, verziu PHP a svoje pozorovanie. Ozveme sa, vyjasníme situáciu a budeme pracovať na diaľku, kým nebude incident uzavretý a zdokumentovaný.

Okamžitá pomoc