Ajankohtainen tilanne: PHP2Shell. Kaksi kriittistä PHP-haavoittuvuutta (CVSS 9.2) sallii haittakoodin suorittamisen ilman kirjautumista. Korjaukset 21.10.2026 alkaen.Mitä nyt on tehtävä →

PHP ja tietokannat: PDO ja mysqli

PHP keskustelee tietokantojen kanssa PDO:n tai mysqlin kautta. Tässä erot, turvalliset kyselyt Prepared Statementsilla ja mitä tietokantatunnuksille tehdään palvelinpoikkeaman jälkeen.

Tilanne Lukuaika 4 minPHP-tietoa

Lyhyesti: PHP käyttää tietokantoja kahden yleisen rajapinnan kautta: PDO (PHP Data Objects) toimii monien tietokantajärjestelmien kanssa yhtenäisellä rajapinnalla, mysqli on räätälöity MySQL:lle ja MariaDB:lle. Molemmilla Prepared Statements eli kyselyt paikkamerkeillä suojaavat luotettavasti SQL-injektiolta. Versiosta PHP 8.0 (PDO) tai 8.1 (mysqli) lähtien molemmat ilmoittavat virheet oletuksena poikkeuksina.

Miten PHP keskustelee tietokantojen kanssa

Lähes jokainen PHP-sovellus tallentaa sisältönsä tietokantaan: sivut, tilaukset, käyttäjätilit, asetukset. PHP-komentosarja muodostaa siihen yhteyden, lähettää kyselyn SQL-kielellä ja käsittelee tuloksen. Tunnukset ovat yleensä konfiguraatiotiedostossa samalla palvelimella.

Johdolle tämä on tärkeää, koska tietokanta sisältää yleensä yrityksen arvokkaimmat tiedot. Joka voi suorittaa koodia verkkopalvelimella, voi yleensä myös lukea konfiguraatiotiedoston ja päästä näillä tunnuksilla tietokantaan.

PDO ja mysqli vertailussa

Ominaisuus PDO mysqli
Tietokannat monta, ajureilla kuten PDO_MYSQL, PDO_PGSQL, PDO_SQLITE, PDO_SQLSRV, PDO_OCI MySQL ja MariaDB
Paikkamerkit nimetyt (:name) ja paikkaan perustuvat (?) paikkaan perustuvat (?)
Tyyli olio-orientoitunut olio-orientoitunut ja proseduraalinen
Virheet poikkeuksina oletus versiosta PHP 8.0.0 oletus versiosta PHP 8.1.0
Lyhytmuoto parametrikyselyille prepare() ja execute() taulukolla execute_query() versiosta PHP 8.2.0

Käytännössä ratkaisun tekee usein kehys tai CMS. Monissa on oma tietokantakerros, joka käyttää sisäisesti PDO:ta tai mysqlia. Joka ottaa sovelluksen haltuunsa, voi yksinkertaisella lähdekoodihaulla selvittää, mitä rajapintaa käytetään ja missä kyselyt syntyvät:

# Missä sovellus muodostaa yhteyksiä, missä kyselyt syntyvät?
grep -rn --include='*.php' -E 'new PDO|new mysqli|mysqli_connect|->query\(' /var/www/app/src | head -50

Löydökset, joissa on ->query(, eivät ole automaattisesti epävarmoja. Ne ansaitsevat silti toisen katseen, koska niissä arvot voivat päätyä suoraan SQL-tekstiin sen sijaan, että ne välitettäisiin paikkamerkkien kautta. Erityisesti vanhemmat projektit sekoittavat molemmat tyylit, ja tarkistus kannattaa ennen jokaista isompaa päivitystä.

Prepared Statements: tärkein malli

Prepared Statementissa kysely lähetetään tietokannalle paikkamerkein ja arvot välitetään erikseen. PHP-käsikirjan mukaan tämä suojaa SQL-injektiolta, kun kaikki käyttäjän syötteet kulkevat paikkamerkkien kautta.

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

Sama mysqlilla lyhytmuodossa, jota on ollut PHP 8.2:sta lähtien:

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

Kehittäjien tulee tuntea kaksi rajaa. Paikkamerkkejä ei saa panna lainausmerkkeihin; LIKE-hauissa jokerimerkit % kuuluvat välitettävään arvoon. Ja paikkamerkit korvaavat vain arvoja, eivät taulujen tai sarakkeiden nimiä. Miten tällaiset erikoistapaukset ratkaistaan turvallisesti, näyttää opas SQL-injektion estäminen PHP:ssä.

Virheenkäsittely: poikkeukset hiljaisten virheiden sijaan

Aiemmin molemmat rajapinnat toimivat oletuksena hiljaisesti: epäonnistunut kysely palautti false, ja jos sitä ei tarkistanut, jatkoi työtä tyhjällä datalla. Tämä on muuttunut:

  • PDO: Versiosta PHP 8.0.0 lähtien PDO::ERRMODE_EXCEPTION on oletus. Virheet heittävät PDOException-poikkeuksen.
  • mysqli: Versiosta PHP 8.1.0 lähtien ilmoitustilaksi on asetettu MYSQLI_REPORT_ERROR ja MYSQLI_REPORT_STRICT. Virheet heittävät mysqli_sql_exception-poikkeuksen; aiemmin ilmoitus oli pois päältä.

Tietoturvan kannalta tämä tarkoittaa: poikkeukset on otettava kiinni ja kirjattava, mutta ne eivät koskaan saa päätyä selaimeen SQL-tekstin, taulujen nimien tai tunnusten kanssa. Miten tämä erotetaan siististi, kuvaa sivu Virheet ja poikkeukset PHP:ssä.

Tunnusten ja oikeuksien oikea antaminen

Tietokanta on suojattu vain niin hyvin kuin sen tunnukset. Nämä säännöt ovat osoittautuneet hyviksi:

  1. Oma käyttäjä sovellusta kohden: Älä koskaan käytä tietokannan ylläpitäjää verkkosivustolle.
  2. Vain tarvittavat oikeudet: Verkkosivusto tarvitsee yleensä lukemisen, kirjoittamisen, muuttamisen ja poistamisen omassa tietokannassaan, mutta ei oikeuksia muihin tietokantoihin tai palvelintoimintoihin.
  3. Ei etäyhteyttä ilman syytä: Tietokannan tulisi olla tavoitettavissa vain verkkopalvelimelta, ei internetistä.
  4. Tunnukset verkkojuuren ulkopuolella: Konfiguraatio- ja .env-tiedostot eivät saa olla haettavissa URL:n kautta. Lisää artikkelissa Tunnusten ja .env-tiedostojen suojaus.
  5. Salattu yhteys erillisillä palvelimilla: Jos tietokanta on toisella koneella, yhteyden tulisi olla salattu, jotta tunnukset ja sisällöt eivät kulje verkossa selkokielisinä.
  6. Omat tunnukset huoltoon: Varmuuskopiointi, raportit ja ylläpitäjät saavat omat käyttäjänsä. Näin lokista voi jäljittää, kuka teki mitä, ja tunnuksen voi sulkea häiritsemättä verkkosivustoa.

Tietokannat, PHP2Shell ja hätätilanne

PHP2Shell ei koske tietokantaa itseään vaan PHP-tulkkia: CVE-2026-109618 ja CVE-2026-109619 sallivat haittakoodin suorittamisen ilman kirjautumista. Jos se onnistuu, koodi toimii PHP-prosessin oikeuksilla ja voi siten yleensä lukea konfiguraatiotiedoston, jossa ovat tietokannan tunnukset. Prepared Statements eivät auta tässä, koska hyökkäys ei kulje lainkaan SQL-kyselyn kautta.

Pakollista on siksi päivitys versioon PHP 8.5.12, 8.4.27, 8.3.36 tai 8.2.35 ja kaikkien PHP-prosessien uudelleenkäynnistys. Jos on viitteitä onnistuneesta hyökkäyksestä, mukaan kuuluvat uudet tietokantatunnukset, tietokannan tarkistus lisätyn sisällön varalta ja GDPR:n mukaisen ilmoitusvelvollisuuden arviointi. Tässä jäsennelty incident response on järkevä.

Vinkki

Vaihtakaa tietokannan salasanat vasta palvelimen puhdistuksen jälkeen. Niin kauan kuin haittakoodi on käynnissä, se voi lukea myös uudet tunnukset uudelleen.

Miten PHP SOS auttaa konkreettisesti?

  • Tarkistamme, miten sovelluksenne käyttää tietokantaa ja vastaavatko käyttäjät, oikeudet ja verkkoyhteys vähimmäistasoa.
  • Varmistamme, että konfiguraatio- ja tunnustiedostot ovat verkkojuuren ulkopuolella eivätkä julkisesti tavoitettavissa.
  • Poikkeaman jälkeen uusimme tunnukset oikeassa järjestyksessä ja tarkistamme tietokannan lisätyn koodin varalta.
  • Dokumentoimme tulokset niin, että tietosuojavastaavat ja vakuuttajat voivat seurata niitä.

Usein kysytyt kysymykset

Pitäisikö minun käyttää PDO:ta vai mysqlia?

Uusissa projekteissa PDO on yleensä joustavampi valinta, koska se toimii monen tietokannan kanssa saman rajapinnan kautta. mysqli on järkevä, jos käytätte yksinomaan MySQL:ää tai MariaDB:tä ja tarvitsette niiden erikoistoimintoja. Molemmat ovat turvallisia, kun Prepared Statementsia käytetään johdonmukaisesti.

Heittääkö PDO virheissä automaattisesti poikkeuksen?

Kyllä, versiosta PHP 8.0.0 lähtien PDO::ERRMODE_EXCEPTION on oletus. Sitä ennen käytössä oli hiljainen tila, jossa virheet olivat saatavilla vain funktioilla errorCode() ja errorInfo(). Vanhemmat sovellukset asettavat tilan usein yhä nimenomaisesti.

Voivatko paikkamerkit korvata myös taulujen tai sarakkeiden nimiä?

Eivät. Paikkamerkit edustavat vain arvoja. Taulujen ja sarakkeiden nimet, esimerkiksi lajittelua varten, on tarkistettava sallittujen nimien kiinteää luetteloa vasten, ennen kuin ne lisätään kyselyyn.

Pitääkö minun vaihtaa tietokannan salasana PHP2Shellin jälkeen?

Pelkkä päivitys ei sitä vaadi. Jos kuitenkin on viitteitä siitä, että palvelin oli vaarantunut, kaikkia konfiguraatiotiedostoissa olevia tunnuksia pidetään tunnettuina. Silloin ne kannattaa uusia puhdistuksen jälkeen.

Lähteet

Pikayhteys

Jokainen tunti on tärkeä. Kirjoittakaa meille nyt.

Kuvatkaa lyhyesti järjestelmä, PHP-versio ja havainnot. Otamme yhteyttä, selvitämme tilanteen ja työskentelemme etänä, kunnes tapaus on käsitelty loppuun ja dokumentoitu.

Pikaapu