Εν ολίγοις: Το φιλτράρισμα αιτημάτων ανεβάσματος στο όριο σημαίνει ότι απορρίπτετε στον proxy, στον διακομιστή ιστού ή στο WAF αιτήματα POST τύπου multipart/form-data, όταν δεν κατευθύνονται σε γνωστή διαδρομή upload. Ειδικοί συγγραφείς το προτείνουν ως προσωρινό, ανεπίσημο μέτρο κατά του PHP2Shell. Μπορεί να χαλάσει φόρμες και ανεβάσματα και δεν αντικαθιστά ποτέ την ενημέρωση. Προχωρήστε σε τρία βήματα: καταγραφή, καθορισμός εξαιρέσεων, μόνο μετά αποκλεισμός, με σταθερή ημερομηνία λήξης.
Μια πρόταση από τη συζήτηση των ειδικών
Μέχρι να ενημερωθεί ένας διακομιστής, οι φορείς λειτουργίας αναζητούν ό,τι μειώνει τον κίνδυνο. Στη συζήτηση των ειδικών για το PHP2Shell εμφανίστηκε μια πρόταση: να επιτρέπονται αιτήματα POST σε μορφή multipart/form-data, δηλαδή τη μορφή για ανεβάσματα αρχείων και ορισμένες φόρμες, μόνο εκεί όπου η εφαρμογή τα αναμένει πραγματικά. Όλα τα άλλα απορρίπτονται στον proxy ή στο Web Application Firewall.
Σημαντική είναι η τοποθέτηση. Η πρόταση δεν προέρχεται από το php.net αλλά από ειδικούς συγγραφείς και προορίζεται ρητά ως προσωρινό μέτρο. Το php.net αναφέρει δικά του μεταβατικά μέτρα, συγκεντρωμένα στο Άμεσα μέτρα όταν δεν μπορείτε ακόμη να εφαρμόσετε patch. Το φίλτρο μπορεί να τα συμπληρώσει, όχι να τα αντικαταστήσει.
Εδώ περιγράφουμε πώς το εισάγετε ελεγχόμενα. Λεπτομέρειες για το γιατί θα μπορούσε να βοηθήσει κατά ποιων επιθέσεων, τις παραλείπουμε σκόπιμα.
Τι προσφέρει το φίλτρο και πού βλάπτει
Η σκέψη πίσω από αυτό είναι η μείωση της επιφάνειας επίθεσης. Οι περισσότερες σελίδες ενός ιστοτόπου δεν χρειάζονται ανεβάσματα αρχείων. Αν μόνο λίγες, γνωστές διαδρομές δέχονται τέτοια αιτήματα, ένα μεγάλο μέρος των πιθανών απόπειρων επίθεσης δεν φτάνει καθόλου στην PHP.
Η άλλη όψη είναι εξίσου σαφής. Κάθε λειτουργία που στέλνει αιτήματα multipart και λείπει από τη λίστα εξαιρέσεων τίθεται εκτός λειτουργίας. Αυτό δεν αφορά μόνο τις προφανείς φόρμες upload.
| Λειτουργία | Χρησιμοποιεί συχνά multipart/form-data | Κίνδυνος σε αποκλεισμό |
|---|---|---|
| Φόρμες επικοινωνίας και αιτήσεων με συνημμένο | ναι | χάνονται αιτήματα |
| Διαχείριση πολυμέσων στο backend του CMS | ναι | η συντακτική ομάδα δεν μπορεί να ανεβάσει εικόνες |
| Εισαγωγή προϊόντων ή πελατών | ναι | οι διεπαφές χαλούν αθόρυβα |
| Φόρμες χωρίς συνημμένο | μερικές φορές | ανάλογα με το εργαλείο δημιουργίας φορμών |
| Διεπαφές και ειδοποιήσεις εξωτερικών υπηρεσιών | σπάνια, αλλά δυνατό | η βλάβη γίνεται αντιληπτή αργά |
Προστίθεται ένα θεμελιώδες πρόβλημα: η Cloudflare, που η ίδια έχει διαθέσει κανόνες προστασίας κατά του PHP2Shell, προειδοποιεί ότι οι κανόνες με βάση μόνο τα δεδομένα του αιτήματος δεν αρκούν. Πώς σκέφτεστε μαζί τα δύο επίπεδα, περιγράφει το WAF ή ενημέρωση: γιατί χρειάζεστε και τα δύο.
Βήμα 1: πρώτα καταγραφή, μετά αποκλεισμός
Προτού αποκλείσετε οτιδήποτε, διαπιστώστε ποιες διαδρομές δέχονται καθόλου αιτήματα multipart. Τα τυπικά logs δεν δείχνουν τον τύπο περιεχομένου. Στο Nginx δημιουργείτε γι' αυτό προσωρινά δικό σας πρωτόκολλο:
# στο μπλοκ http
map $uri $upload_pfad {
default 0;
~^/kontakt/upload\.php$ 1;
~^/admin/medien/ 1;
}
map "$request_method:$upload_pfad:$content_type" $multipart_fremd {
default 0;
"~*^POST:0:multipart/form-data" 1;
}
log_format multipart '$time_iso8601 $remote_addr "$request" "$content_type" $status';
# στο μπλοκ server
# Προσοχή: ένα access_log στο μπλοκ server αντικαθιστά το κληρονομημένο πρωτόκολλο,
# γι' αυτό δηλώστε εδώ ξανά το κανονικό log.
access_log /var/log/nginx/access.log combined;
access_log /var/log/nginx/multipart-test.log multipart if=$multipart_fremd;
Οι εγγραφές στο $upload_pfad είναι παραδείγματα. Ξεκινήστε με κενή λίστα εξαιρέσεων, τότε το πρωτόκολλο δοκιμής δείχνει όλα τα POST multipart. Στον Apache το ίδιο επιτυγχάνεται με μια μεταβλητή περιβάλλοντος:
# στο VirtualHost
SetEnvIfNoCase Content-Type "^multipart/form-data" ist_multipart
CustomLog ${APACHE_LOG_DIR}/multipart-test.log combined env=ist_multipart
Αφήστε το πρωτόκολλο να λειτουργεί μερικές ημέρες, ιδανικά σε περίοδο όπου ήταν ενεργοί και η συντακτική ομάδα, οι υποψήφιοι και οι διεπαφές.
Βήμα 2: καθορισμός εξαιρέσεων και ελεγχόμενος αποκλεισμός
Από το πρωτόκολλο δοκιμής εξάγετε τις διαδρομές που χρειάζονται θεμιτά ανεβάσματα. Συγκρίνετε τη λίστα με τους υπευθύνους: ποιος συντηρεί περιεχόμενο, ποιες φόρμες υπάρχουν, ποιες υπηρεσίες στέλνουν δεδομένα;
- Δημιουργήστε λίστα εξαιρέσεων από το πρωτόκολλο και τις ερωτήσεις και καταχωρίστε την στο
$upload_pfadαντίστοιχα στις γραμμέςRewriteCond. - Ενεργοποιήστε το φίλτρο πρώτα σε περιβάλλον δοκιμών ή σε ήσυχο χρονικό παράθυρο.
- Δοκιμάστε οι ίδιοι όλες τις φόρμες, τα ανεβάσματα και τις διαδρομές παραγγελιών.
- Παρακολουθήστε το πρωτόκολλο σφαλμάτων για αιτήματα που απορρίφθηκαν (κατάσταση 403) και συμπληρώστε τη λίστα αν χρειαστεί.
- Καθορίστε ημερομηνία λήξης: μετά την ενημέρωση της PHP και την επανεκκίνηση όλων των workers, το φίλτρο αφαιρείται ξανά.
Στο Nginx προσθέτετε γι' αυτό τον αποκλεισμό στο μπλοκ server:
# στο μπλοκ server, μετά την αξιολόγηση της φάσης καταγραφής
if ($multipart_fremd) {
return 403;
}
Στον Apache το έργο αναλαμβάνει το mod_rewrite. Σύμφωνα με την τεκμηρίωση του Apache, πολλαπλές συνθήκες συνδέονται με ΚΑΙ:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} =POST
RewriteCond %{HTTP:Content-Type} ^multipart/form-data [NC]
RewriteCond %{REQUEST_URI} !^/kontakt/upload\.php$
RewriteCond %{REQUEST_URI} !^/admin/medien/
RewriteRule ^ - [F]
Αν χρησιμοποιείτε CDN ή WAF στο cloud, η ίδια λογική μπορεί συχνά να αποτυπωθεί ως δικός σας κανόνας. Και εκεί ισχύει: πρώτα σε λειτουργία καταγραφής, μετά αποκλεισμός.
Το φίλτρο δεν αντικαθιστά την ενημέρωση της PHP και δεν αποτελεί λόγο αναβολής της. Το PHP2Shell διορθώνεται μόνο με PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 ή επιβεβαιωμένο backport, ακολουθούμενο από επανεκκίνηση όλων των διεργασιών PHP.
Σωστή τοποθέτηση του μέτρου
Το φίλτρο ανεβασμάτων ανήκει σε μια σειρά με άλλες προτάσεις που κυκλοφορούν αυτή την περίοδο. Ορισμένες είναι λογικές, άλλες επιζήμιες. Μια επισκόπηση των συμβουλών που απορρίπτουν ειδικοί συγγραφείς, για παράδειγμα τον αποκλεισμό όλων των αιτημάτων με cookie session, δίνει το Επικίνδυνες λανθασμένες συμβουλές για το PHP2Shell.
Πώς επεξεργάζεται η PHP εσωτερικά τα ανεβάσματα και γιατί η μορφή multipart/form-data παίζει εκεί ιδιαίτερο ρόλο, εξηγεί το Πώς επεξεργάζεται η PHP τα ανεβάσματα αρχείων. Για τις περισσότερες επιχειρήσεις το σημαντικότερο βήμα δεν είναι το φίλτρο, αλλά ένας σαφής χρόνος για την ενημέρωση.
Συμπέρασμα: ένα εργαλείο για ημέρες, όχι για μήνες
Το φίλτρο ανεβασμάτων στο όριο είναι τυπικό παράδειγμα μέτρου έκτακτης ανάγκης: μπορεί να μικρύνει την επιφάνεια επίθεσης στη μεταβατική περίοδο, έχει όμως παρενέργειες και δεν έχει επίσημη υποστήριξη από το php.net. Σωστά εφαρμοσμένο, με φάση καταγραφής, συντονισμένη λίστα εξαιρέσεων, δοκιμές και σταθερή ημερομηνία λήξης, είναι υπεράσπιστο. Χωρίς αυτά τα βήματα διακινδυνεύετε χαμένες αιτήσεις εργασίας, αποκλεισμένες συντακτικές ομάδες και αθόρυβα σφάλματα διεπαφών.
Πάρτε γι' αυτό την απόφαση συνειδητά και καταγράψτε ποιος την πήρε και πότε. Και έχετε στον νου τη σειρά: πρώτα έρχεται η ενημέρωση της PHP με επανεκκίνηση όλων των workers, τα μεταβατικά μέτρα του php.net γεφυρώνουν τον χρόνο μέχρι τότε και το φίλτρο είναι το πολύ ένα πρόσθετο στρώμα.
Πώς βοηθά συγκεκριμένα η PHP SOS;
- Αξιολόγηση της κατάστασης: Διευκρινίζουμε αν ένα φίλτρο ανεβασμάτων έχει καν νόημα στη δική σας περίπτωση ή αν η ενημέρωση είναι δυνατή ταχύτερα.
- Καταγραφή και αξιολόγηση: Στήνουμε τη φάση καταγραφής και εξάγουμε τη λίστα εξαιρέσεων από πραγματικές προσβάσεις.
- Ελεγχόμενος αποκλεισμός: Ενεργοποιούμε το φίλτρο, δοκιμάζουμε φόρμες και διαδρομές παραγγελιών και παρακολουθούμε τα αιτήματα που απορρίπτονται.
- Καθαρή αποσύνδεση: Στο πλαίσιο του WAF και του εικονικού patching αφαιρούμε το φίλτρο μετά την ενημέρωση.
Συχνές ερωτήσεις
Είναι το φιλτράρισμα αιτημάτων multipart επίσημη σύσταση του php.net;
Όχι. Το php.net αναφέρει άλλα μεταβατικά μέτρα, για παράδειγμα όρια για το post_max_size και την απενεργοποίηση του session.upload_progress. Το φιλτράρισμα στο όριο είναι πρόταση από ειδικά άρθρα και προορίζεται ρητά μόνο ως προσωρινό μέτρο.
Ποιες λειτουργίες μπορεί να σταματήσουν εξαιτίας του φίλτρου;
Οτιδήποτε στέλνει αρχεία ή φόρμες σε μορφή multipart και δεν βρίσκεται στη λίστα εξαιρέσεών σας: φόρμες επικοινωνίας με συνημμένο, φόρμες αιτήσεων εργασίας, διαχείριση πολυμέσων στο CMS, λειτουργίες εισαγωγής, ορισμένες διεπαφές και ειδοποιήσεις πληρωμών. Γι' αυτό πριν από τον αποκλεισμό προηγείται μια φάση καταγραφής.
Αντικαθιστά το φίλτρο την ενημέρωση της PHP;
Όχι. Μειώνει το πολύ την επιφάνεια επίθεσης στη μεταβατική περίοδο. Η Cloudflare επισημαίνει η ίδια ότι οι κανόνες με βάση μόνο τα δεδομένα του αιτήματος δεν αρκούν. Το PHP2Shell διορθώνεται μόνο με διορθωμένη έκδοση PHP και επανεκκίνηση όλων των workers.
Να αποκλείσω αντί γι' αυτό αιτήματα με PHPSESSID;
Όχι. Αυτή η συμβουλή που κυκλοφορεί απορρίπτεται ρητά από ειδικούς συγγραφείς. Παραλύει συνδέσεις και καλάθια αγορών, χωρίς να προσφέρει αξιόπιστη προστασία.