Hardening WordPressa przez .htaccess – 13 reguł, które stosuję na każdej stronie

Plik .htaccess to jedno z najprostszych i najskuteczniejszych narzędzi do utwardzania WordPressa na serwerze Apache lub LiteSpeed. Nie zastąpi aktualizacji ani firewalla, ale odcina całe klasy automatycznych ataków, zanim w ogóle dotrą do PHP.
Zanim zaczniesz: zrób kopię obecnego pliku .htaccess. Jeden błąd składni kończy się błędem 500 na całej stronie – z kopią naprawisz go w kilka sekund. Reguły poniżej dotyczą Apache 2.4 i LiteSpeed. Na serwerze Nginx robi się to inaczej.
1. Wyłącz listowanie katalogów
Options -Indexes
Bez tej linijki ktoś może otworzyć np. /wp-content/uploads/2026/ i przejrzeć wszystkie pliki, łącznie z tymi, których nie podlinkowałeś.
2. Zablokuj dostęp do wrażliwych plików
<FilesMatch "^(wp-config\.php|readme\.html|license\.txt|wp-config-sample\.php|\.user\.ini)$">
Require all denied
</FilesMatch>
wp-config.php zawiera hasło do bazy danych. Plik readme.html zdradza wersję WordPressa, co ułatwia dobranie gotowego exploita.
3. Zablokuj XML-RPC, jeśli go nie używasz
<Files xmlrpc.php>
Require all denied
</Files>
XML-RPC to ulubiony cel ataków brute-force, bo w jednym żądaniu można sprawdzić setki haseł. Uwaga: korzysta z niego m.in. Jetpack i starsze aplikacje mobilne – sprawdź to przed blokadą.
4. Zakaz uruchamiania PHP w katalogu uploads
W katalogu wp-content/uploads/ utwórz osobny plik .htaccess:
<FilesMatch "\.(php|php\d|phtml|phar)$">
Require all denied
</FilesMatch>
To jedna z najważniejszych reguł. Jeśli przez dziurawą wtyczkę ktoś wgra plik PHP do katalogu z obrazkami, nie będzie mógł go uruchomić.
5. Utrudnij wyliczanie loginów użytkowników
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/wp-admin [NC]
RewriteCond %{QUERY_STRING} ^author=\d+ [NC]
RewriteRule ^ - [F]
Adres ?author=1 przekierowuje na stronę autora i zdradza jego login. Pamiętaj, że loginy ujawnia też REST API (/wp-json/wp/v2/users) – to zamykam już wtyczką lub kodem w motywie.
6. Nagłówki bezpieczeństwa
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>
.htaccess to zamek w drzwiach, nie cały system alarmowy. Działa najlepiej razem z aktualizacjami, firewallem aplikacyjnym i kopiami zapasowymi.
7. Zablokuj bezpośredni dostęp do plików wp-includes
Pliki PHP w katalogu wp-includes są ładowane przez WordPress, a nie wywoływane bezpośrednio z przeglądarki. Poniższy zestaw reguł pochodzi z oficjalnej dokumentacji „Hardening WordPress”:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
Uwaga: tej reguły nie stosuj w instalacji WordPress Multisite – blokuje plik ms-files.php.
8. Ukryj pliki systemowe i repozytoria (.git, .env)
RewriteRule (^|/)\.(?!well-known/) - [F]
Reguła blokuje wszystkie ścieżki zaczynające się od kropki: .git, .env, .svn, .htpasswd. Wyjątkiem jest katalog .well-known, którego potrzebuje m.in. Let's Encrypt do odnawiania certyfikatu SSL. Odsłonięty katalog .git pozwala pobrać cały kod strony razem z historią zmian – a czasem i hasłami.
9. Zablokuj kopie zapasowe i zrzuty bazy
<FilesMatch "\.(sql|bak|old|orig|save|swp|log|tar|gz)$">
Require all denied
</FilesMatch>
Pliki typu wp-config.php.bak czy backup.sql zostawione w katalogu strony to prezent dla atakującego – serwer nie wykona ich jako PHP, tylko odda treść, łącznie z hasłem do bazy. Jeśli udostępniasz klientom archiwa do pobrania, wyłącz z reguły gz i tar albo przenieś je do osobnego katalogu.
10. Odfiltruj najprostsze złośliwe zapytania
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} (\.\./|%2e%2e%2f) [NC]
RewriteRule ^ - [F]
Reguła zatrzymuje najprymitywniejsze próby XSS, nadpisywania zmiennych PHP i wychodzenia poza katalog (../). To nie jest pełny firewall – traktuj ją jako pierwsze sito przed WAF-em.
11. Odetnij skanery i puste User-Agenty
RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} (sqlmap|nikto|wpscan|masscan|zgrab|nmap) [NC]
RewriteRule ^ - [F]
Zautomatyzowane narzędzia często przedstawiają się wprost albo nie wysyłają nagłówka User-Agent wcale. Sprytniejszy atakujący łatwo to obejdzie, ale reguła skutecznie ogranicza szum w logach i obciążenie serwera.
12. Nie zdradzaj wersji serwera i PHP
ServerSignature Off
<IfModule mod_headers.c>
Header always unset X-Powered-By
Header unset X-Powered-By
</IfModule>
Nagłówek X-Powered-By: PHP/8.x i podpis serwera na stronach błędów podpowiadają, jakich luk szukać. Pełne wyłączenie wersji Apache (ServerTokens Prod) wymaga dostępu do konfiguracji serwera – na hostingu współdzielonym poproś o to administratora.
13. Wymuś HTTPS i HSTS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000"
</IfModule>
HSTS każe przeglądarce łączyć się ze stroną wyłącznie przez HTTPS przez wskazany czas. Włączaj go dopiero wtedy, gdy certyfikat działa poprawnie na wszystkich adresach – źle ustawiony HSTS potrafi na długo zablokować dostęp do strony. Parametr includeSubDomains dodawaj tylko, jeśli wszystkie subdomeny mają SSL.
Gdzie wkleić reguły?
Wszystkie reguły umieszczaj nad blokiem # BEGIN WordPress … # END WordPress. WordPress nadpisuje zawartość tego bloku przy zmianie ustawień bezpośrednich odnośników, więc reguły wklejone do środka po prostu znikną. Reguły dla katalogu uploads (punkt 4) trafiają do osobnego pliku wp-content/uploads/.htaccess. Ochronę strony logowania opisałem szerzej we wpisie o zabezpieczaniu wp-login.php i 2FA.
Do tego koniecznie w wp-config.php:
define('DISALLOW_FILE_EDIT', true);– wyłącza edytor plików motywu i wtyczek w kokpicie.- Unikalne klucze i sole (wygenerujesz je na api.wordpress.org/secret-key/1.1/salt/).
- Prefiks tabel inny niż domyślny
wp_przy nowych instalacjach.
Po wdrożeniu reguł przetestuj stronę: logowanie, formularze, koszyk, wtyczki korzystające z AJAX. Jeśli coś przestało działać – wiesz, którą regułę wycofać.
Najczęstsze pytania
Co to jest hardening WordPressa?
Hardening to utwardzanie – zestaw ustawień, które zamykają niepotrzebne furtki: blokada XML-RPC, ochrona pliku wp-config.php, zakaz uruchamiania PHP w katalogu uploads oraz nagłówki bezpieczeństwa. Celem jest zmniejszenie liczby miejsc, przez które można zaatakować stronę.
Czy edycja pliku .htaccess jest bezpieczna?
Tak, o ile najpierw zrobisz kopię pliku. Błąd w .htaccess może wywołać błąd 500, ale wystarczy wtedy przywrócić kopię. Zmiany wprowadzaj pojedynczo i po każdej sprawdzaj, czy strona działa.
Czy reguły .htaccess działają na każdym serwerze?
Na serwerach Apache i LiteSpeed tak. Na Nginx odpowiedniki tych reguł ustawia się w konfiguracji serwera – wtedy plik .htaccess nie jest brany pod uwagę.
Potrzebujesz pomocy z tym tematem?
MAQ Enterprise zajmie się tym za Ciebie – od jednorazowego audytu po stałą opiekę nad stroną. Zadzwoń: +48 604 790 398 lub napisz.
Napisz do mnie

