Jak zabezpieczyć plik wp-login.php przed atakami typu brute force

Zabezpieczenie

Ataki typu brute force to dla każdego użytkownika WordPressa chleb powszedni. Praktycznie każda strona oparta na tym CMSie jest mniej lub bardziej intensywnie atakowana przez automaty próbujące zalogować się na konto administratora, korzystając najczęściej z metody słownikowej (używając listy najpopularniejszych haseł). Ataki takie są bardzo charakterystyczne i łatwo je znaleźć w logach serwera – wystarczy zwrócić uwagę na częste żądania wysyłane do pliku wp-login.php, który służy do autoryzacji użytkowników.

Teoretycznie, jeśli stosujemy się do podstawowych zasad bezpieczeństwa, atakujący ma małe szanse na powodzenie. Jednak duża ilość tego typu prób ataków może spowolnić naszą stronę, a w najgorszym razie doprowadzić nawet do całkowitego jej unieruchomienia. Dlatego też dobrze jest zabezpieczyć się i zablokować całkowicie tego typu działania.

Każde żądanie wysyłane do pliku wp-login.php zużywa trochę zasobów serwera. Jeśli korzystamy z hostingu współdzielonego, to w skrajnym przypadku może to doprowadzić do zablokowania naszego konta z powodu przekroczenia limitów wykorzystania zasobów (czasu procesora, zapytań do bazy danych itp.).

Do zablokowania ataków skierowanych na wp-login.php można wykorzystać jedną z dostępnych wtyczek. Kompleksowe rozwiązania, takie jak WordFence czy iThemes Security, robią mnóstwo rzeczy mających poprawić bezpieczeństwo naszej strony. Używanie tego typu wtyczek jest generalnie dobrym pomysłem, ale w tym akurat konkretnym przypadku prostsze sposoby są lepsze.

Najskuteczniejszą metodą ochrony przed skutkami ataków typu brute force jest zablokowanie ich zanim dotrą do naszej strony, czyli na poziomie serwera HTTP (można zrobić to jeszcze wcześniej, ale z przyczyn technicznych najczęściej nie jesteśmy tego w stanie tego wykonać). Wtyczki blokujące ataki brute force są napisane (tak jak i sam WordPress) w PHP, tak więc angażują interpreter tego języka, co powoduje dodatkowe (niepotrzebne) obciążenie serwera.

Większość firm hostingowych korzysta z serwera Apache i na nim skupię się w dalszej części tego wpisu.

Najprostszą metodą na zablokowanie dostępu do pliku wp-login.php jest dodanie takiego wpisu do pliku .htaccess:


order deny,allow
deny from all
allow from 123.123.123.123

Wpis ten blokuje całkowicie wszystkie żądania wysyłane do tego pliku, za wyjątkiem żądań z adresu IP 123.123.123.123 (tutaj należy wpisać własny adres IP, który można sprawdzić na przykład tutaj). Nic oczywiście nie stoi na przeszkodzie, aby odblokować dostęp z kilku adresów – wystarczy dodać kolejne linie allow from.

Tej metody nie ma sensu stosować na stronach, które pozwalają użytkownikom na rejestrację i logowanie.

Problem z tą metodą pojawia się w momencie, gdy nasz adres IP jest zmienny (większość dostawców łącz wymusza co jakiś czas zmianę IP). Ponieważ po zmianie adresu zostaniemy pozbawieni możliwości zalogowania się do panelu administracyjnego strony, konieczne będzie albo wprowadzenie aktualnego IP do pliku .htaccess, albo użycie innej metody.


RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{HTTP_REFERER} !^http://(.*)?.nasza-domena.pl [NC]
RewriteCond %{REQUEST_URI} ^/wp-login\.php(.*)$
RewriteRule ^(.*)$ - [R=403,L]

Powyższy kod blokuje wszystkie wysyłane do pliku wp-login.php żądania typu POST, które nie posiadają nagłówka Referer z adresem w naszej domenie. Automaty najczęściej w ogóle nie przekazują tego nagłówka, tak więc metoda ta w większości przypadków się sprawdzi. Problem polega na tym, że spora część atakujących najpierw wysyła żądanie typu GET (którego tą metodą nie zablokujemy), a dopiero potem POST. Rozwiązaniem jest usunięcie z powyższego kodu linii RewriteCond %{REQUEST_METHOD} POST, co z kolei utrudni nam nieco dostęp do strony logowania (nie będziemy mogli wejść na nią bezpośrednio).

Poza plikiem wp-login.php często atakowany jest również plik xmlrpc.php. Jeśli nie korzystamy z interfejsu XML-RPC, warto całkowicie zablokować dostęp do tego pliku dodając do .htaccess następujący wpis:


order deny,allow
deny from all

Zdjęcie: David Hamilton

Bezpośredni link