Μετάβαση στο περιεχόμενο
Server & .htaccess

Κανόνες ασφαλείας .htaccess για WordPress που πραγματικά βοηθούν

Τα περισσότερα από όσα πωλούνται ως ασφάλεια .htaccess για WordPress είναι απλώς γέμισμα. Οι κανόνες που πραγματικά αλλάζουν την επιφάνεια επίθεσής σου είναι λίγοι — δες ποιοι είναι ποιοι

Δημοσιεύτηκε

Τα περισσότερα από όσα πωλούνται ως «ασφάλεια .htaccess για WordPress» είναι απλώς γέμισμα. Οι κανόνες που πραγματικά αλλάζουν την επιφάνεια επίθεσής σου είναι λίγοι: μπλόκαρε την εκτέλεση PHP μέσα στο wp-content/uploads, απαγόρευσε την άμεση πρόσβαση στο wp-config.php και απενεργοποίησε το directory indexing. Οι δημοφιλείς κανόνες — το μπλοκάρισμα του xmlrpc.php «για να σταματήσεις τις επιθέσεις brute force», η απόκρυψη της έκδοσης του WordPress, η επικόλληση μιας λίστας 200 γραμμών με user-agent κακόβουλων bot — κυμαίνονται από οριακά χρήσιμοι μέχρι καθαρό θέατρο. Παρακάτω θα δεις ποιος είναι ποιος, και γιατί.

Ένα πράγμα να ξεκαθαρίσουμε πρώτα: το .htaccess κάνει κάτι μόνο σε Apache (και σε LiteSpeed, που επίσης το διαβάζει). Σε nginx αγνοείται εντελώς — το αρχείο απλώς κάθεται εκεί ενώ εσύ νομίζεις ότι είσαι προστατευμένος. Αν ο host σου τρέχει nginx, τίποτα από αυτά δεν ισχύει και χρειάζεσαι μπλοκ server/location αντ’ αυτού. Έλεγξέ το με curl -I https://yoursite.com και κοίτα την κεφαλίδα Server: πριν χαλάσεις μία ώρα επεξεργαζόμενος ένα αρχείο που ο server δεν διαβάζει ποτέ.

Ο κανόνας που πραγματικά μετράει: καθόλου PHP στο /uploads

Αυτός είναι που αξίζει να τον κάνεις. Το wp-content/uploads είναι εξ ορισμού εγγράψιμο από τους πάντες — κάθε ανέβασμα αρχείου media, κάθε πρόσθετο που αποθηκεύει αρχείο, γράφει εκεί. Αν ένας επιτιθέμενος καταφέρει να βάλει ένα αρχείο .php μέσα σε αυτόν τον φάκελο (μέσω ενός ευάλωτου upload handler, ενός πεδίου εικόνας που δεν επικυρώνει τον τύπο MIME, ενός παραβιασμένου πρόσθετου), η διαφορά ανάμεσα σε μια ενόχληση και σε μια πλήρη παραβίαση με απομακρυσμένη εκτέλεση κώδικα είναι το αν ο server θα εκτελέσει αυτό το αρχείο όταν ζητηθεί. Απαγόρευσε την εκτέλεση και το ανεβασμένο payload είναι απλώς ένα αδρανές αρχείο που κάθεται στον δίσκο.

Ρίξε αυτό μέσα στο wp-content/uploads/.htaccess (δημιούργησε το αρχείο αν δεν υπάρχει):

<FilesMatch "\.php$">
    Require all denied
</FilesMatch>

Αυτό είναι σύνταξη του Apache 2.4. Στο παλαιότερο 2.2, το αντίστοιχο είναι Order Deny,Allow / Deny from all. Το ανακάτεμα των δύο διαλέκτων στο ίδιο αρχείο είναι η πιο συχνή αιτία ενός ξαφνικού 500 Internal Server Error μετά το «hardening» — αν όλο το site πέσει τη στιγμή που αποθηκεύεις, σχεδόν πάντα αυτός είναι ο λόγος. Έλεγξε την έκδοσή σου με apachectl -v.

Προστάτεψε το wp-config.php

Το wp-config.php περιέχει τα διαπιστευτήρια της βάσης δεδομένων σου και τα auth salts. Όσο τρέχει η PHP, ένα άμεσο αίτημα σε αυτό επιστρέφει μια κενή σελίδα — η PHP εκτελεί το αρχείο αντί να το εμφανίσει. Ο κίνδυνος είναι η περίπτωση αποτυχίας: αν η PHP κρασάρει, ρυθμιστεί λάθος κατά τη διάρκεια μιας μετάβασης, ή απενεργοποιηθεί ο handler, ο Apache σερβίρει το αρχείο ως απλό κείμενο και ξεφορτώνει τον κωδικό της βάσης σου σε όποιον τον ζητήσει. Η απαγόρευση της πρόσβασης είναι φθηνή ασφάλεια απέναντι σε ένα άσχημο πεντάλεπτο:

<Files wp-config.php>
    Require all denied
</Files>

Απενεργοποίησε το directory indexing

Αν κάποιος επισκεφτεί έναν φάκελο χωρίς index.php και ο Apache έχει το Options +Indexes ενεργό, εμφανίζει τα περιεχόμενα — κάθε αρχείο backup, κάθε ξεχασμένο SQL dump. Απενεργοποίησέ το σε όλο το site:

Options -Indexes

Χαμηλής σοβαρότητας, αλλά υπαρκτό, και δεν κοστίζει τίποτα.

Αυτή είναι η ειλικρινής βασική λίστα. Μπορείς να τα συναρμολογήσεις — μαζί με τη σωστή σύνταξη 2.4 έναντι 2.2 ώστε να μην ρίξεις το site σου με 500 — χρησιμοποιώντας τον WordPress .htaccess generator αντί να αντιγράψεις-επικολλήσεις από μια ανάρτηση σε φόρουμ γραμμένη για λάθος έκδοση Apache.

Τι να ΜΗΝ κάνεις

Το μπλοκάρισμα του xmlrpc.php «για προστασία από brute force». Αυτό είναι το μεγάλο που όλοι επαναλαμβάνουν και είναι λάθος όπως διατυπώνεται. Ναι, η μέθοδος system.multicall του XML-RPC ιστορικά επέτρεπε σε έναν επιτιθέμενο να πακετάρει πολλές απόπειρες σύνδεσης σε ένα μόνο αίτημα — πραγματική ενίσχυση. Όμως ο συντριπτικά πιο συνηθισμένος φορέας brute force είναι απλά αιτήματα POST στο wp-login.php, και το μπλοκάρισμα του xmlrpc.php δεν κάνει τίποτα γι’ αυτό. Το brute force αντιμετωπίζεται με rate limiting, ισχυρούς κωδικούς και 2FA — όχι σκοτώνοντας ένα endpoint. Υπάρχει ένας θεμιτός λόγος να απενεργοποιήσεις το XML-RPC: η λειτουργία pingback του μπορεί να καταχραστεί για ανάκλαση DDoS, οπότε αν δεν χρησιμοποιείς Jetpack, την εφαρμογή για κινητά ή τα pingbacks, το κλείσιμό του μειώνει την επιφάνεια επίθεσής σου. Απλώς μην πείθεις τον εαυτό σου ότι είναι η άμυνά σου απέναντι στο brute force, γιατί δεν είναι.

Η απόκρυψη της έκδοσης του WordPress / η αφαίρεση του generator tag. Η αφαίρεση του readme.html και του tag <meta name="generator"> μοιάζει με hardening. Ένας επιτιθέμενος αναγνωρίζει την έκδοσή σου από τα query strings των enqueued assets, το markup του block-editor και μια ντουζίνα άλλα σημάδια μέσα σε δευτερόλεπτα. Δεν κρύβεις τίποτα· απλώς κάνεις τον εαυτό σου να νιώθει απασχολημένος.

Τεράστιες λίστες μπλοκαρίσματος με user-agent κακόβουλων bot και referrer. Τα user agents είναι μία μόνο πλαστογραφημένη κεφαλίδα HTTP. Αυτές οι λίστες είναι ξεπερασμένες την ίδια μέρα που τις επικολλάς, δεν μπλοκάρουν τίποτα ικανό, και ο Apache αξιολογεί κάθε regex σε κάθε αίτημα — πληρώνεις έναν πραγματικό φόρο επιδόσεων για μηδενική ασφάλεια. Παράλειψέ τες.

Το κλείδωμα του wp-login.php σε συγκεκριμένη IP. Τέλειο μέχρι ο ISP σου να εναλλάξει τη διεύθυνσή σου και να κλειδωθείς έξω από τον δικό σου πίνακα διαχείρισης. Βιώσιμο μόνο με μια πραγματικά στατική IP.

Ανακατευθύνσεις για author enumeration (?author=1). Το rewrite του .htaccess που επικολλά ο κόσμος γι’ αυτό είναι από μόνο του ελλιπές — το REST endpoint /wp-json/wp/v2/users εξακολουθεί να εμφανίζει τα ονόματα χρηστών. Το μπλοκάρισμα του ενός μονοπατιού ενώ το άλλο μένει ανοιχτό είναι θέατρο.

Ακόμα κολλημένος;

Αν ένας κανόνας ρίχνει το site με 500, είναι θέμα σύνταξης — αφαίρεσε το τελευταίο μπλοκ που πρόσθεσες και ανανέωσε· αυτό το απομονώνει αμέσως. Αν ένας κανόνας φαίνεται να μην κάνει τίποτα, επιβεβαίωσε ότι είσαι πράγματι σε Apache και ότι το AllowOverride είναι ενεργοποιημένο για τον φάκελο (πολλοί managed hosts το περιορίζουν). Φτιάξε το αρχείο από ένα δοκιμασμένο template με τον .htaccess generator, κράτα τους τρεις κανόνες που μετράνε και άφησε τους υπόλοιπους.