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

Απαγόρευση εκτέλεσης PHP σε φακέλους upload

Ένα webshell χρειάζεται δύο πράγματα: έναν φάκελο όπου μπορεί να γραφτεί και έναν διακομιστή που το εκτελεί. Δείτε πώς του αφαιρείτε το δεύτερο, και μάλιστα σε κάθε εγγράψιμο φάκελο και όχι μόνο στο uploads.

Ημερομηνία 6 λεπτά ανάγνωσηςΣκλήρυνση και διαμόρφωση

Εν ολίγοις: Για να απαγορεύσετε την εκτέλεση PHP στα uploads, εντοπίζετε πρώτα όλους τους φακέλους στους οποίους επιτρέπεται να γράφει η PHP και αποκλείετε στη συνέχεια σε καθέναν από αυτούς την εκτέλεση σεναρίων στη διαμόρφωση του διακομιστή, όχι με .htaccess. Στο Nginx ο αποκλεισμός πρέπει να ισχύει πριν από το γενικό μπλοκ PHP, στον Apache ανήκει στο VirtualHost με AllowOverride None. Το security.limit_extensions = .php στο pool FPM και μια δοκιμή με αθώο αρχείο ολοκληρώνουν τη δουλειά.

Γιατί μετρούν τώρα ιδιαίτερα οι φάκελοι upload

Μετά από μια κρίσιμη ευπάθεια όπως το PHP2Shell, οι επιτιθέμενοι σπάνια θέλουν να εκτελέσουν κώδικα μόνο μία φορά. Θέλουν να επιστρέψουν, ακόμη κι αν ο διακομιστής ενημερωθεί αργότερα. Ο απλούστερος δρόμος γι' αυτό είναι ένα webshell: ένα μικρό αρχείο PHP, που αποτίθεται σε εγγράψιμο φάκελο και καλείται αργότερα μέσω του περιηγητή.

Ένα patch δεν αφαιρεί ένα τέτοιο αρχείο. Όποιος ήταν online χωρίς patch από τις 20 Οκτωβρίου 2026, πρέπει γι' αυτό όχι μόνο να ενημερώσει, αλλά και να ελέγξει αν κάπου βρίσκονται νέα αρχεία PHP και να εμποδίσει στο εξής την εκτέλεσή τους. Πώς ερμηνεύονται τα ευρήματα, περιγράφει το Αρχεία PHP στον φάκελο upload: σωστή ερμηνεία των ευρημάτων.

Ο αποκλεισμός εκτέλεσης στοχεύει τη δεύτερη προϋπόθεση. Δεν εμποδίζει την απόθεση ενός αρχείου, αλλά τον διακομιστή να το αντιμετωπίσει ως πρόγραμμα.

Πρώτα η απογραφή: πού επιτρέπεται να γράφει η PHP;

Οι περισσότεροι οδηγοί αναφέρουν μόνο τον φάκελο upload. Στην πράξη μια εφαρμογή PHP γράφει σε πολύ περισσότερα σημεία. Καθένα από αυτά που είναι προσβάσιμο μέσω του διακομιστή ιστού χρειάζεται τον αποκλεισμό.

Τύπος φακέλου Τυπικό περιεχόμενο Γιατί είναι εγγράψιμος
Uploads, πολυμέσα εικόνες, PDF, συνημμένα χρήστες και συντάκτες ανεβάζουν αρχεία
Cache σελίδες που δημιουργούνται, μικρογραφίες η εφαρμογή επιταχύνει την παράδοση
Temp, import, export αρχεία CSV, ενδιάμεσες καταστάσεις διεπαφές και ανταλλαγή δεδομένων
Backups στο webroot .zip, .sql επεκτάσεις δημιουργούν αντίγραφα «επιτόπου»
Logs στο webroot logs σφαλμάτων και debug λανθασμένα διαμορφωμένες εφαρμογές

Ποιοι φάκελοι είναι αυτοί στον διακομιστή σας, το δείχνει μια αναζήτηση με τα δικαιώματα του χρήστη εκτέλεσης. Δεν αλλάζει τίποτα:

# Όλοι οι φάκελοι κάτω από το /var/www στους οποίους επιτρέπεται να γράφει ο χρήστης της PHP
# (προσαρμόστε τον χρήστη: www-data, nginx, apache ή δικός σας χρήστης pool)
sudo -u www-data find /var/www -type d -writable 2>/dev/null | sort
# Υπάρχουν ήδη αρχεία PHP σε αυτούς τους φακέλους;
sudo -u www-data find /var/www -type d -writable -print0 2>/dev/null \
  | xargs -0 -I{} find {} -maxdepth 1 -type f -iname "*.ph*" 2>/dev/null

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

Απαγόρευση εκτέλεσης PHP στα uploads: Nginx

Στο Nginx αποφασίζει η σειρά. Σύμφωνα με την τεκμηρίωση του Nginx, οι κανονικές εκφράσεις ελέγχονται με τη σειρά του αρχείου διαμόρφωσης και κερδίζει η πρώτη αντιστοίχιση. Αν το γενικό μπλοκ location ~ \.php$ βρίσκεται πριν από τον αποκλεισμό σας, το αρχείο εκτελείται. Ένα απλό location με πρόθεμα χωρίς ^~ δεν προστατεύει για τον ίδιο λόγο.

Ασφαλής είναι μια κανονική έκφραση για όλους τους αποκλεισμένους φακέλους, που βρίσκεται πριν από το μπλοκ PHP. Καλύπτει και σπάνια χρησιμοποιούμενες καταλήξεις:

server {
    # ... βασική διαμόρφωση ...

    # 1. Αποκλεισμός για εγγράψιμους φακέλους, ΠΡΕΠΕΙ να βρίσκεται πριν από το μπλοκ PHP
    location ~* ^/(uploads|media|cache|tmp|export)/.*\.(php\d?|phtml|phar|pht|phps)$ {
        deny all;
    }

    # 2. Γενικό μπλοκ PHP: παράδοση μόνο υπαρχόντων αρχείων
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/seite1.sock;
    }
}

Προσαρμόστε τα ονόματα των φακέλων στην απογραφή σας. Σε εφαρμογές με ένα μοναδικό σημείο εισόδου ο δρόμος μέσω λίστας επιτρεπόμενων είναι ακόμη ισχυρότερος· το μοτίβο δείχνει το Ασφαλής διαμόρφωση του Nginx για PHP.

Apache και PHP-FPM: ο αποκλεισμός στο σωστό σημείο

Στον Apache ο αποκλεισμός ανήκει στη διαμόρφωση του διακομιστή ή στο VirtualHost. Ένα .htaccess στον φάκελο upload είναι ακατάλληλο, επειδή μπορεί να το αλλάξει όποιος επιτρέπεται να γράφει εκεί. Για ολόκληρο το webroot ισχύει γι' αυτό AllowOverride None. Σύμφωνα με την τεκμηρίωση του Apache, το AllowOverride επιτρέπεται μόνο σε μπλοκ <Directory> χωρίς κανονικές εκφράσεις, άρα το ορίζετε στο webroot και τον αποκλεισμό με <DirectoryMatch> από κάτω:

<Directory /var/www/seite1/public>
    AllowOverride None
    Require all granted
</Directory>

<DirectoryMatch "^/var/www/seite1/public/(uploads|media|cache|tmp|export)/">
    <FilesMatch "\.(php\d?|phtml|phar|pht|phps)$">
        Require all denied
    </FilesMatch>
</DirectoryMatch>

Αν εκτελείται ακόμη mod_php, προσθέστε στο ίδιο μπλοκ php_admin_flag engine off. Στο PHP-FPM ενεργεί ένα δεύτερο φράγμα στο pool: το security.limit_extensions ορίζει ποιες καταλήξεις εκτελεί καθόλου το FPM. Σύμφωνα με το εγχειρίδιο της PHP η προεπιλογή είναι .php .phar· συνιστάται ο περιορισμός σε .php.

; στο pool, π.χ. /etc/php/8.3/fpm/pool.d/seite1.conf
security.limit_extensions = .php

Δοκιμή με αθώο αρχείο

Το αν ο αποκλεισμός λειτουργεί το δείχνει μόνο μια δοκιμή. Τοποθετήστε για λίγο σε κάθε αποκλεισμένο φάκελο ένα αρχείο που απλώς εμφανίζει ένα κείμενο, καλέστε το μέσω του domain και διαγράψτε το στη συνέχεια.

  1. Ελέγξτε τη διαμόρφωση: nginx -t αντίστοιχα apachectl configtest, μετά επαναφόρτωση.
  2. Δημιουργήστε αρχείο δοκιμής, για παράδειγμα uploads/sperrtest.php με περιεχόμενο <?php echo 'ausgefuehrt';.
  3. Καλέστε το με curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/uploads/sperrtest.php. Αναμένεται 403.
  4. Αν εμφανιστεί αντί γι' αυτό 200 και το κείμενο «ausgefuehrt», ο αποκλεισμός δεν ισχύει. Ελέγξτε τη διαμόρφωση και τη σειρά.
  5. Διαγράψτε το αρχείο δοκιμής και επαναλάβετε τη δοκιμή για κάθε φάκελο και κάθε ιστότοπο.
Σημαντικό

Αν στην απογραφή βρείτε ήδη άγνωστα αρχεία PHP σε εγγράψιμους φακέλους, μη διαγράψετε τίποτα βιαστικά. Διασφαλίστε πρώτα την κατάσταση και τα logs, επειδή αυτά τα αρχεία αποτελούν αποδεικτικά στοιχεία. Πώς προχωράτε στη συνέχεια, περιγράφει το Αναγνώριση και αφαίρεση webshells.

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

Συμπέρασμα: εγγραφή ναι, εκτέλεση όχι

Ο αποκλεισμός εκτέλεσης σε εγγράψιμους φακέλους είναι ένα από τα αποτελεσματικότερα μεμονωμένα μέτρα κατά των μόνιμων κερκόπορτων. Κοστίζει λίγες γραμμές διαμόρφωσης και δεν χαλάει τίποτα σε σωστά φτιαγμένες εφαρμογές. Αποφασιστικά είναι τρία πράγματα: μια πλήρης απογραφή αντί μόνο του προφανούς φακέλου upload, η σωστή σειρά στο Nginx αντίστοιχα το σωστό επίπεδο στον Apache και μια πραγματική δοκιμή με αθώο αρχείο.

Συμπληρωμένο με χωριστούς ιδιοκτήτες για τον κώδικα του προγράμματος, το security.limit_extensions στο pool και μια τακτική αναζήτηση νέων αρχείων PHP, προκύπτει μια κατάσταση όπου ένα αρχείο που αποτέθηκε είναι μεν ενοχλητικό, αλλά σχεδόν αναξιοποίητο. Αυτό δεν αντικαθιστά ούτε την ενημέρωση ούτε την αναζήτηση ιχνών, αφαιρεί όμως από τους επιτιθέμενους ένα από τα σημαντικότερα εργαλεία τους.

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

  • Απογραφή: Εντοπίζουμε όλους τους εγγράψιμους φακέλους ανά ιστότοπο και τους ελέγχουμε για υπάρχοντα αρχεία PHP.
  • Ορισμός αποκλεισμών: Καταχωρίζουμε τους αποκλεισμούς εκτέλεσης σε Nginx, Apache και PHP-FPM, με τη σωστή σειρά και χωρίς εξάρτηση από .htaccess.
  • Δοκιμή: Ελέγχουμε κάθε αποκλεισμό με αθώο αρχείο και τεκμηριώνουμε το αποτέλεσμα.
  • Καθαρισμός: Σε περίπτωση ευρημάτων αναλαμβάνουμε τη διασφάλιση ιχνών και την αφαίρεση κακόβουλου λογισμικού.

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

Αρκεί ένα .htaccess στον φάκελο upload για να απαγορευτεί η PHP;

Όχι αξιόπιστα. Όποιος μπορεί να γράψει στον φάκελο, μπορεί να αλλάξει ή να αντικαταστήσει και το .htaccess. Ο αποκλεισμός ανήκει στη διαμόρφωση του διακομιστή ή στο VirtualHost και για το webroot πρέπει να ισχύει AllowOverride None.

Ποιους φακέλους πρέπει να αποκλείσω;

Όλους τους φακέλους στους οποίους επιτρέπεται να γράφει ο χρήστης της PHP και οι οποίοι είναι προσβάσιμοι μέσω του διακομιστή ιστού. Εκτός από τους φακέλους upload, συχνά είναι φάκελοι cache, temp, import, export και backup. Εντοπίστε τους με αναζήτηση ως χρήστης εκτέλεσης.

Θα χαλάσει ο αποκλεισμός τον ιστότοπό μου;

Κατά κανόνα όχι, επειδή σε φακέλους upload και cache δεν βρίσκονται, στις σωστά φτιαγμένες εφαρμογές, σενάρια που καλούνται απευθείας. Ορισμένες επεκτάσεις αποθέτουν όμως εκεί αρχεία PHP. Δοκιμάστε γι' αυτό μετά τη μετάβαση τις σημαντικότερες λειτουργίες.

Προστατεύει ο αποκλεισμός από το PHP2Shell;

Όχι. Το PHP2Shell είναι ευπάθεια στον διερμηνέα PHP, που κλείνει μόνο με την ενημέρωση και την επανεκκίνηση όλων των workers. Ο αποκλεισμός εμποδίζει όμως ένα αρχείο που έχει αποτεθεί να κληθεί αργότερα μέσω του περιηγητή και να χρησιμοποιηθεί ως μόνιμη κερκόπορτα.

Πηγές

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

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

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

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