Τρέχουσα κατάσταση: PHP2Shell. Δύο κρίσιμες ευπάθειες της PHP (CVSS 9.2) επιτρέπουν κακόβουλο κώδικα χωρίς σύνδεση. Patches από τις 21/10/2026.Τι πρέπει να γίνει τώρα →

PHP και βάσεις δεδομένων: PDO και mysqli

Η PHP μιλά με βάσεις δεδομένων μέσω PDO ή mysqli. Εδώ βλέπετε τις διαφορές, ασφαλή ερωτήματα με prepared statements και τι πρέπει να γίνει με τα στοιχεία πρόσβασης στη βάση μετά από ένα περιστατικό στον διακομιστή.

Ημερομηνία 6 λεπτά ανάγνωσηςΓνώση PHP

Εν συντομία: Η PHP προσπελαύνει βάσεις δεδομένων μέσω δύο διαδεδομένων διεπαφών: το PDO (PHP Data Objects) εργάζεται με πολλά συστήματα βάσεων δεδομένων μέσω ενιαίας διεπαφής, το mysqli είναι προσαρμοσμένο σε MySQL και MariaDB. Και με τα δύο, τα prepared statements, δηλαδή ερωτήματα με placeholders, προστατεύουν αξιόπιστα από SQL injection. Από την PHP 8.0 (PDO) αντίστοιχα 8.1 (mysqli) και τα δύο αναφέρουν σφάλματα από προεπιλογή ως exception.

Πώς μιλά η PHP με τις βάσεις δεδομένων

Σχεδόν κάθε εφαρμογή PHP αποθηκεύει το περιεχόμενό της σε μια βάση δεδομένων: σελίδες, παραγγελίες, λογαριασμούς χρηστών, ρυθμίσεις. Το σενάριο PHP δημιουργεί γι' αυτό μια σύνδεση, στέλνει ένα ερώτημα στη γλώσσα SQL και επεξεργάζεται το αποτέλεσμα. Τα στοιχεία πρόσβασης βρίσκονται συνήθως σε ένα αρχείο διαμόρφωσης στον ίδιο διακομιστή.

Για τη διοίκηση αυτό είναι σημαντικό, επειδή η βάση δεδομένων περιέχει συνήθως τα πολυτιμότερα δεδομένα της επιχείρησης. Όποιος μπορεί να εκτελέσει κώδικα στον διακομιστή ιστού, μπορεί κατά κανόνα να διαβάσει και το αρχείο διαμόρφωσης και να προσπελάσει με αυτά τα στοιχεία πρόσβασης τη βάση δεδομένων.

Σύγκριση PDO και mysqli

Χαρακτηριστικό PDO mysqli
Βάσεις δεδομένων πολλές, μέσω οδηγών όπως PDO_MYSQL, PDO_PGSQL, PDO_SQLITE, PDO_SQLSRV, PDO_OCI MySQL και MariaDB
Placeholders ονομασμένα (:name) και θεσιακά (?) θεσιακά (?)
Στυλ αντικειμενοστρεφές αντικειμενοστρεφές και διαδικαστικό
Σφάλματα ως exception προεπιλογή από την PHP 8.0.0 προεπιλογή από την PHP 8.1.0
Σύντομη μορφή για ερωτήματα με παραμέτρους prepare() και execute() με πίνακα execute_query() από την PHP 8.2.0

Στην πράξη αποφασίζει συχνά το framework ή το CMS. Πολλά φέρνουν δικό τους επίπεδο βάσης δεδομένων, που χρησιμοποιεί εσωτερικά PDO ή mysqli. Όποιος αναλαμβάνει μια εφαρμογή, μπορεί με μια απλή αναζήτηση στον πηγαίο κώδικα να διαπιστώσει ποια διεπαφή χρησιμοποιείται και πού δημιουργούνται τα ερωτήματα:

# Πού δημιουργεί η εφαρμογή συνδέσεις, πού δημιουργούνται ερωτήματα;
grep -rn --include='*.php' -E 'new PDO|new mysqli|mysqli_connect|->query\(' /var/www/app/src | head -50

Τα ευρήματα με ->query( δεν είναι αυτόματα ανασφαλή. Αξίζουν όμως μια δεύτερη ματιά, επειδή εκεί οι τιμές μπορούν να καταλήξουν απευθείας στο κείμενο SQL, αντί να παραδίδονται μέσω placeholders. Ιδίως τα παλαιότερα έργα αναμειγνύουν και τα δύο στυλ και ο έλεγχος αξίζει πριν από κάθε μεγαλύτερη ενημέρωση.

Prepared statements: το σημαντικότερο πρότυπο

Σε ένα prepared statement το ερώτημα στέλνεται στη βάση δεδομένων με placeholders και οι τιμές παραδίδονται ξεχωριστά. Σύμφωνα με το εγχειρίδιο της PHP, αυτό προστατεύει από SQL injection, όταν όλες οι εισαγωγές χρηστών περνούν μέσω placeholders.

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

Το ίδιο με το mysqli στη σύντομη μορφή που υπάρχει από την 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";
}

Δύο όρια πρέπει να γνωρίζουν οι προγραμματιστές. Οι placeholders δεν επιτρέπεται να βρίσκονται σε εισαγωγικά· στις αναζητήσεις με LIKE οι χαρακτήρες μπαλαντέρ % ανήκουν στην τιμή που παραδίδεται. Και οι placeholders αντικαθιστούν μόνο τιμές, όχι ονόματα πινάκων ή στηλών. Πώς λύνονται με ασφάλεια τέτοιες ειδικές περιπτώσεις, δείχνει ο οδηγός Αποτροπή SQL injection στην PHP.

Διαχείριση σφαλμάτων: exceptions αντί για σιωπηλά σφάλματα

Παλαιότερα και οι δύο διεπαφές λειτουργούσαν από προεπιλογή σιωπηλά: ένα αποτυχημένο ερώτημα επέστρεφε false και όποιος δεν το έλεγχε, συνέχιζε να εργάζεται με κενά δεδομένα. Αυτό άλλαξε:

  • PDO: Από την PHP 8.0.0 το PDO::ERRMODE_EXCEPTION είναι η προεπιλογή. Τα σφάλματα ρίχνουν ένα PDOException.
  • mysqli: Από την PHP 8.1.0 η αναφορά σφαλμάτων έχει οριστεί σε MYSQLI_REPORT_ERROR και MYSQLI_REPORT_STRICT. Τα σφάλματα ρίχνουν ένα mysqli_sql_exception· προηγουμένως η αναφορά ήταν απενεργοποιημένη.

Για την ασφάλεια αυτό σημαίνει: τα exceptions πρέπει να πιάνονται και να καταγράφονται, δεν επιτρέπεται όμως ποτέ να καταλήγουν στον browser με κείμενο SQL, ονόματα πινάκων ή στοιχεία πρόσβασης. Πώς διαχωρίζεται αυτό σωστά, περιγράφει η σελίδα Σφάλματα και exceptions στην PHP.

Σωστή απόδοση στοιχείων πρόσβασης και δικαιωμάτων

Η βάση δεδομένων προστατεύεται μόνο όσο καλά προστατεύονται τα στοιχεία πρόσβασής της. Αυτοί οι κανόνες έχουν αποδειχθεί:

  1. Ξεχωριστός χρήστης ανά εφαρμογή: Ποτέ μην χρησιμοποιείτε τον διαχειριστή της βάσης δεδομένων για τον ιστότοπο.
  2. Μόνο τα απαραίτητα δικαιώματα: Ένας ιστότοπος χρειάζεται συνήθως ανάγνωση, εγγραφή, αλλαγή και διαγραφή στη δική του βάση δεδομένων, όχι όμως δικαιώματα σε άλλες βάσεις ή σε λειτουργίες του διακομιστή.
  3. Καμία απομακρυσμένη σύνδεση χωρίς λόγο: Η βάση δεδομένων πρέπει να είναι προσβάσιμη μόνο από τον διακομιστή ιστού, όχι από το διαδίκτυο.
  4. Στοιχεία πρόσβασης εκτός του webroot: Τα αρχεία διαμόρφωσης και .env δεν επιτρέπεται να είναι προσβάσιμα μέσω URL. Περισσότερα στη σελίδα Προστασία στοιχείων πρόσβασης και αρχείων .env.
  5. Κρυπτογραφημένη σύνδεση σε χωριστούς διακομιστές: Αν η βάση δεδομένων βρίσκεται σε άλλον υπολογιστή, η σύνδεση πρέπει να είναι κρυπτογραφημένη, ώστε στοιχεία πρόσβασης και περιεχόμενο να μη διέρχονται από το δίκτυο ως απλό κείμενο.
  6. Ξεχωριστές πρόσβαση για τη συντήρηση: Η δημιουργία αντιγράφων ασφαλείας, οι αναλύσεις και οι διαχειριστές αποκτούν δικούς τους χρήστες. Έτσι μπορεί να αναπαραχθεί στο log ποιος έκανε τι και μια πρόσβαση μπορεί να κλειδωθεί χωρίς να ενοχληθεί ο ιστότοπος.

Βάσεις δεδομένων, PHP2Shell και η περίπτωση έκτακτης ανάγκης

Το PHP2Shell δεν αφορά την ίδια τη βάση δεδομένων, αλλά τον διερμηνέα PHP: τα CVE-2026-109618 και CVE-2026-109619 επιτρέπουν την εκτέλεση κακόβουλου κώδικα χωρίς σύνδεση χρήστη. Αν το πετύχουν, ο κώδικας εκτελείται με τα δικαιώματα της διεργασίας PHP και μπορεί έτσι κατά κανόνα να διαβάσει το αρχείο διαμόρφωσης με τα στοιχεία πρόσβασης στη βάση δεδομένων. Τα prepared statements δεν βοηθούν απέναντι σε αυτό, επειδή η επίθεση δεν περνά καθόλου μέσω ερωτήματος SQL.

Υποχρεωτική είναι γι' αυτό η ενημέρωση στις PHP 8.5.12, 8.4.27, 8.3.36 ή 8.2.35 και η επανεκκίνηση όλων των διεργασιών PHP. Αν υπάρχουν ενδείξεις επιτυχούς επίθεσης, ανήκουν σε αυτό νέα στοιχεία πρόσβασης στη βάση δεδομένων, έλεγχος της βάσης για κακόβουλο περιεχόμενο και αξιολόγηση της υποχρέωσης γνωστοποίησης σύμφωνα με τον ΓΚΠΔ. Εδώ έχει νόημα μια δομημένη αντιμετώπιση περιστατικών (Incident Response).

Συμβουλή

Αλλάξτε τους κωδικούς πρόσβασης της βάσης δεδομένων μόνο μετά τον καθαρισμό του διακομιστή. Όσο εκτελείται κακόβουλος κώδικας, μπορεί να διαβάσει ξανά και τα νέα στοιχεία πρόσβασης.

Πώς βοηθά συγκεκριμένα η PHP SOS;

  • Ελέγχουμε πώς προσπελαύνει η εφαρμογή σας τη βάση δεδομένων και αν οι χρήστες, τα δικαιώματα και η πρόσβαση δικτύου αντιστοιχούν στο ελάχιστο απαραίτητο.
  • Ελέγχουμε αν τα αρχεία διαμόρφωσης και στοιχείων πρόσβασης βρίσκονται εκτός του webroot και δεν είναι δημόσια προσβάσιμα.
  • Μετά από ένα περιστατικό ανανεώνουμε τα στοιχεία πρόσβασης με τη σωστή σειρά και ελέγχουμε τη βάση δεδομένων για κακόβουλο κώδικα.
  • Τεκμηριώνουμε τα αποτελέσματα με τρόπο ώστε να μπορούν να τα παρακολουθήσουν οι υπεύθυνοι προστασίας δεδομένων και οι ασφαλιστές.

Συχνές ερωτήσεις

Πρέπει να χρησιμοποιήσω PDO ή mysqli;

Για νέα έργα το PDO είναι συνήθως η πιο ευέλικτη επιλογή, επειδή λειτουργεί με πολλές βάσεις δεδομένων μέσω της ίδιας διεπαφής. Το mysqli έχει νόημα αν χρησιμοποιείτε αποκλειστικά MySQL ή MariaDB και χρειάζεστε τις ειδικές τους λειτουργίες. Και τα δύο είναι ασφαλή, όταν τα prepared statements χρησιμοποιούνται συστηματικά.

Ρίχνει το PDO αυτόματα exceptions σε σφάλματα;

Ναι, από την PHP 8.0.0 το PDO::ERRMODE_EXCEPTION είναι η προεπιλογή. Προηγουμένως ήταν η σιωπηλή λειτουργία, όπου τα σφάλματα ήταν διαθέσιμα μόνο μέσω errorCode() και errorInfo(). Οι παλαιότερες εφαρμογές ορίζουν συχνά ακόμη ρητά τη λειτουργία.

Μπορούν οι placeholders να αντικαταστήσουν και ονόματα πινάκων ή στηλών;

Όχι. Οι placeholders αντιπροσωπεύουν μόνο τιμές. Τα ονόματα πινάκων και στηλών, για παράδειγμα για μια ταξινόμηση, πρέπει να ελέγχονται απέναντι σε μια σταθερή λίστα επιτρεπόμενων ονομάτων προτού εισαχθούν στο ερώτημα.

Πρέπει μετά το PHP2Shell να αλλάξω τον κωδικό της βάσης δεδομένων;

Η ενημέρωση από μόνη της δεν το απαιτεί. Αν υπάρχουν όμως ενδείξεις ότι ο διακομιστής είχε παραβιαστεί, όλα τα στοιχεία πρόσβασης σε αρχεία διαμόρφωσης θεωρούνται γνωστά. Τότε πρέπει να τα ανανεώσετε μετά τον καθαρισμό.

Πηγές

Άμεση επικοινωνία

Κάθε ώρα μετράει. Γράψτε μας τώρα.

Περιγράψτε σύντομα το σύστημα, την έκδοση PHP και ό,τι παρατηρείτε. Θα επικοινωνήσουμε μαζί σας, θα διευκρινίσουμε την κατάσταση και θα εργαστούμε εξ αποστάσεως μέχρι το περιστατικό να κλείσει και να τεκμηριωθεί.

Άμεση βοήθεια