secaudit.eu
Zabezpieczenia

Ochrona WordPress przed brute force: co potrafi wtyczka

Ochrona WordPressa przed atakami brute force warstwa po warstwie: limity logowania, XML-RPC multicall, enumeracja użytkowników w REST i granice wtyczek wobec DDoS.

Autorka: , AngelForce OÜ 7 min czytania

Także po: English Deutsch Français Español Italiano Português Türkçe

Wtyczka bezpieczeństwa dobrze spowalnia zgadywanie haseł. Nie zatrzyma natomiast zalewu ruchu. Ochrona WordPressa przed atakami brute force i ochrona przed DDoS to dwa różne problemy, a każdy rozwiązuje się na innej warstwie: na poziomie kont, samego WordPressa, serwera WWW i sieci brzegowej przed nim.

Artykuł omawia ataki, które najczęściej widać w logach: nieudane logowania na wp-login.php, serie żądań do xmlrpc.php, enumerację użytkowników przez REST API i skoki ruchu. Przy każdym wskazano warstwę, która faktycznie może go zatrzymać. Każde zabezpieczenie dostaje też jedno zdanie o tym, czego nie robi.

Ochrona przed brute force działa warstwowo

Ruch z internetu przechodzi przez kilka warstw, zanim dotrze do Państwa danych. Im dalej od serwera zatrzymane zostaje żądanie, tym mniej kosztuje. Żądanie odrzucone przez CDN nigdy nie dotyka serwera. Żądanie odrzucone przez wtyczkę WordPressa zdążyło już zająć połączenie sieciowe, proces serwera WWW i worker PHP.

Diagram warstw: CDN lub zapora brzegowa, serwer WWW, wtyczka WordPress i konta
Gdzie zatrzymywany jest każdy atak: zalew ruchu na brzegu sieci, nadużycia logowania w WordPressie i na koncie

Z grubsza wygląda to tak:

AtakNajlepsza warstwa
Zgadywanie hasełKonto (2FA) + wtyczka
XML-RPC multicallWtyczka lub serwer WWW
Enumeracja REST, scrapingWtyczka + brzeg sieci
Atak wolumetrycznyCDN / brzeg sieci, hosting

Ograniczanie prób logowania: jak spowolnić zgadywanie haseł na wp-login.php

Mechanizm ten zlicza nieudane próby i reaguje: wydłuża opóźnienia, na pewien czas blokuje źródło albo wymaga rozwiązania zadania weryfikacyjnego. Domyślnie WordPress nie ma żadnego limitu. Atakujący może próbować haseł na wp-login.php tak szybko, jak odpowiada serwer.

Limity per adres IP dobrze działają przeciwko jednemu hałaśliwemu źródłu. Gorzej radzą sobie z botnetem, który rozkłada próby na tysiące adresów, a każdy z nich mieści się w limicie. Dlatego potrzebne są też limity per nazwa użytkownika. Dwadzieścia nieudanych prób na konto „admin" z dwudziestu różnych adresów IP to nadal wzorzec.

Limity per użytkownik mają jednak własną pułapkę. Twarda blokada pozwala każdemu zablokować prawdziwego administratora, wystarczy celowo się pomylić. Rosnące opóźnienia lub zadanie weryfikacyjne są łagodniejsze niż pełna blokada.

O tym, czy ograniczanie pomoże, czy zaszkodzi, decydują dwie rzeczy:

  • Adres IP klienta. Za CDN lub reverse proxy każde żądanie może wyglądać, jakby pochodziło z adresu proxy. Wtyczka, która widzi tylko ten adres, zablokuje wszystkich odwiedzających naraz. Odwrotny błąd jest równie zły: jeśli wtyczka ufa nagłówkowi X-Forwarded-For od każdego, atakujący podstawi nowy adres w każdym żądaniu i nigdy nie zostanie zablokowany. Wtyczkę (albo moduł real-IP serwera WWW) trzeba skonfigurować tak, by przyjmowała przekazywane nagłówki wyłącznie z zakresów IP własnego proxy.
  • Własna droga powrotu. Jeśli biuro ma stały adres IP, warto dodać go do listy dozwolonych. Ścieżkę odzyskiwania dostępu trzeba znać, zanim będzie potrzebna.

Czego ograniczanie prób nie robi: nie czyni bezpiecznym słabego ani powtórnie używanego hasła. Hasło z listy wycieków może zadziałać już za pierwszym razem. Prawdziwym rozwiązaniem jest drugi składnik dla każdego konta z podwyższonymi uprawnieniami, skonfigurowany tak, jak opisano w artykule o uwierzytelnianiu dwuskładnikowym dla administratorów WordPressa.

XML-RPC: dlaczego system.multicall zamienia jedno żądanie w wiele prób

xmlrpc.php jest w WordPressie włączony domyślnie. To stary interfejs zdalnej publikacji, a jedna z jego metod, system.multicall, wykonuje wiele wywołań w jednym żądaniu HTTP. Atakujący może zmieścić długą listę par login/hasło w pojedynczym żądaniu POST.

Omija to zabezpieczenia, które pilnują tylko wp-login.php albo liczą żądania. Jeden wpis w logu może oznaczać setki prób odgadnięcia hasła. Trzeba upewnić się, że ograniczanie logowania zlicza także nieudane uwierzytelnienia przez XML-RPC, albo całkowicie usunąć tę powierzchnię ataku.

Pingbacki XML-RPC można też wykorzystać, by strona wysyłała żądania do osób trzecich. To kolejny powód, by je wyłączyć, jeśli nic ich nie potrzebuje.

Przed wyłączeniem XML-RPC: co jeszcze z niego korzysta

Niektóre prawowite narzędzia nadal łączą się z xmlrpc.php. Wchodzą w grę starsze desktopowe narzędzia do blogowania i zdalnej publikacji, starsze konfiguracje aplikacji mobilnych, niektóre wtyczki-łączniki oraz integracje budowane lata temu. Połączenie Jetpacka historycznie opierało się na XML-RPC, więc jeśli z niego korzystacie, sprawdźcie aktualną dokumentację.

Najpierw trzeba zajrzeć do logów dostępu. Na typowym serwerze Apache lub nginx z formatem logów combined:

# Które adresy IP wysyłają żądania POST do xmlrpc.php?
grep "POST /xmlrpc.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head

# Jakie user-agenty?
awk -F'"' '/POST \/xmlrpc.php/ {print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

Ścieżkę należy dostosować do serwera (na przykład /var/log/apache2/access.log) i uwzględnić zarchiwizowane logi. Tysiące trafień ze zmieniających się adresów IP i z ogólnikowymi user-agentami to ataki. Kilka żądań z jednego znanego adresu usługi to prawdopodobnie integracja, więc przed odcięciem warto zapytać agencję lub dostawcę.

Są dwie możliwości:

  1. **Filtr xmlrpc_enabled.** Wyłącza metody XML-RPC wymagające uwierzytelnienia, co zatrzymuje zgadywanie haseł przez XML-RPC. Metody bez uwierzytelnienia, takie jak pingbacki, nadal działają. Zob. dokumentację dla deweloperów WordPressa.
  2. Zablokowanie pliku na poziomie serwera. Zatrzymuje wszystko, a PHP w ogóle się nie uruchamia dla tych żądań.
<Files xmlrpc.php>
    Require all denied
</Files>
location = /xmlrpc.php {
    deny all;
}

Po zmianie należy przetestować publikowanie, aplikację i każdą podłączoną usługę. Warto zapisać, co i dlaczego zmieniono, żeby następna osoba nie „naprawiła" tego z powrotem.

Enumeracja użytkowników przez REST API i limity dla ruchu anonimowego

/wp-json/wp/v2/users wypisuje użytkowników, którzy opublikowali treści, razem z ich slugami. /?author=1 przekierowuje do archiwum autora, które ujawnia slug w adresie URL. Slug często pokrywa się z loginem, co daje atakującemu połowę danych logowania.

Ograniczenie dostępu anonimowych odwiedzających do endpointu użytkowników i blokowanie skanowania autorów zmniejsza szum rozpoznania. Nazwy użytkowników nie są jednak tajemnicą. Ich ukrywanie nie jest samodzielnym zabezpieczeniem.

Limity dla anonimowych żądań REST pomagają przeciwko scrapingowi i automatycznemu sondowaniu. Należy stosować je wyłącznie do ruchu anonimowego i potem przetestować. Edytor blokowy korzysta z REST API dla zalogowanych użytkowników, a integracje uwierzytelniają się przez hasła aplikacji (Application Passwords, w rdzeniu od WordPressa 5.6). Limit, który to obejmie, zepsuje edycję albo zadanie synchronizacji w sposób trudny do wyśledzenia.

Czego to nie robi: limitowanie nie naprawia podatnego endpointu REST we wtyczce. Tylko spowalnia próby jego wykorzystania.

Dlaczego wtyczka nie zatrzyma ataku DDoS

Wtyczka to kod PHP. Uruchamia się dopiero wtedy, gdy żądanie przeszło przez sieć, zostało przyjęte przez serwer WWW i przekazane workerowi PHP. Atak wolumetryczny wysyca łącze, limity połączeń lub pulę workerów PHP na długo przed tym momentem. Nawet jeśli wtyczka odrzuci każde żądanie w milisekundę, każde odrzucenie nadal zajmuje workera, a serwer ma ich ograniczoną liczbę.

Ataki na warstwę aplikacji wyglądają inaczej. To mnóstwo kosztownych, ale pozornie poprawnych żądań, na przykład zapytań wyszukiwarki albo stron bez cache. Tu limity bliżej aplikacji trochę pomagają, ale tylko do granicy wydajności serwera.

Alert wtyczki o skoku ruchu jest przydatny, bo mówi, że coś się dzieje. Niczego jednak nie pochłania. Każdy produkt, który nazywa wtyczkę WordPressa „ochroną przed DDoS", obiecuje za dużo.

Co zamiast tego robi CDN lub zapora brzegowa i co może dodać serwer WWW

CDN lub zapora brzegowa stoi przed hostingiem, w sieci wielokrotnie większej niż Państwa. Może pochłaniać i filtrować zalew ruchu, stosować limity i reguły antybotowe, zanim ruch do Państwa dotrze, serwować strony z cache, gdy serwer ma kłopoty, oraz wystawiać zadania weryfikacyjne dla żądań do wp-login.php i xmlrpc.php. Gdy jest już wdrożona, trzeba zamknąć origin: na zaporze serwera dopuścić tylko zakresy IP CDN. W przeciwnym razie atakujący obejdą CDN i uderzą w prawdziwy adres serwera.

Na serwerze WWW [moduł limit_req w nginx](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html) może ograniczyć próby logowania, zanim wystartuje PHP. Za CDN lub reverse proxy najpierw trzeba skonfigurować moduł real-IP (ufając tylko zakresom własnego proxy); w przeciwnym razie $binary_remote_addr to adres proxy i wszyscy odwiedzający dzielą jeden limit:

# kontekst http
limit_req_zone $binary_remote_addr zone=wplogin:10m rate=5r/m;

# kontekst server
location = /wp-login.php {
    limit_req zone=wplogin burst=5 nodelay;
    # zachowaj tutaj dotychczasowe linie fastcgi_pass / include
}

fail2ban działa inaczej. Czyta logi i banuje recydywistów na zaporze, co jest tańsze niż odpowiadanie na ich żądania w PHP. Za CDN w tej postaci to nie zadziała: zapora serwera widzi tylko adresy CDN, więc bany muszą następować na poziomie CDN (lub przez jego API). U dostawców hostingu zarządzanego warto zapytać, jaką ochronę sieciową host już zapewnia.

Granice są tu takie same. Zapora brzegowa nie naprawi słabych haseł ani podatnych wtyczek. Nie pomoże też przy tym, co atakujący może zrobić po zalogowaniu, a o tym jest artykuł o wyłączaniu edytora plików w WordPressie.

Kolejność wdrażania dla małych firm w UE

  1. Silne, unikalne hasła i 2FA dla każdego administratora i redaktora.
  2. Ograniczanie prób logowania z limitami per adres IP i per nazwa użytkownika, poprawnym wykrywaniem adresu IP klienta i przetestowaną ścieżką odzyskiwania dostępu.
  3. Decyzja w sprawie XML-RPC: sprawdzić logi, następnie użyć filtra albo blokady na serwerze.
  4. Ograniczenia enumeracji użytkowników i limity dla anonimowych żądań REST.
  5. CDN lub zapora brzegowa z zamkniętym originem dla stron, na których przestój kosztuje.

Ma to znaczenie także dla zgodności z przepisami. Art. 32 ust. 1 lit. b RODO wymaga zapewnienia stałej poufności, integralności, dostępności i odporności systemów (RODO w EUR-Lex). Dla podmiotów objętych zakresem dyrektywy NIS2 art. 21 ust. 2 lit. j wymienia uwierzytelnianie wieloskładnikowe wśród minimalnych środków (NIS2 w EUR-Lex). Szczegóły należy sprawdzić w krajowych przepisach wdrażających NIS2.

Wtyczka Security Audit & Compliance z secaudit.eu oferuje ograniczanie prób logowania, wyłączanie XML-RPC, limity dla anonimowych żądań REST i alerty o skokach ruchu. Nie jest ochroną przed DDoS; do tego służy CDN lub zapora brzegowa. → secaudit.eu

Następny krok: przejść pozostałe punkty listy kontrolnej bezpieczeństwa WordPressa. Jeśli w logach widać już udane logowania, których nie rozpoznajecie, zajrzyjcie zamiast tego do artykułu o oznakach zhakowanej strony.

FAQ

Czy wyłączenie XML-RPC zepsuje Jetpacka lub moją aplikację?

Może. Należy sprawdzić w logach, czy są prawowici klienci XML-RPC, i zajrzeć do aktualnej dokumentacji dostawcy. Filtr xmlrpc_enabled jest opcją łagodniejszą, blokada na poziomie serwera – ostrzejszą. Po każdej z tych zmian trzeba wszystko przetestować.

Czy zmiana nazwy wp-login.php zatrzyma brute force?

Zmniejsza szum od prostych botów, ale nie jest zabezpieczeniem. Atakujący nadal mogą znaleźć stronę logowania albo użyć XML-RPC. Potrzebne są także ograniczanie prób i 2FA.

Czy wtyczka bezpieczeństwa wystarczy podczas ataku DDoS?

Nie. Trzeba skontaktować się z hostingodawcą lub dostawcą CDN. Stronę dostępną utrzymują filtrowanie na brzegu sieci i cache.

Czy ograniczanie prób mnie zablokuje?

Może, jeśli adres IP klienta jest wykrywany błędnie albo wielokrotnie pomylisz hasło. Warto dodać swój adres do listy dozwolonych i mieć pod ręką WP-CLI lub dostęp SFTP, by móc wyłączyć wtyczkę.

Ten artykuł ma charakter ogólnej informacji i nie stanowi porady prawnej.

Sprawdź swoją stronę

Security Audit & Compliance to wtyczka WordPress od secaudit.eu: wyszukuje złośliwe oprogramowanie, ukryty spam, zmienione pliki rdzenia i podatny kod oraz przypisuje wyniki do art. 32 RODO, art. 21 NIS2 i OWASP Top 10.

Zobacz, co sprawdza wtyczka
Melike Görel

Melike Görel pisze poradniki secaudit.eu o bezpieczeństwie WordPressa i zgodności z przepisami UE dla AngelForce OÜ — firmy programistycznej z Tallinna, która stoi za secaudit.eu.

Przygotowano z pomocą AI i sprawdzono przed publikacją. Ten artykuł ma charakter ogólnoinformacyjny i nie stanowi porady prawnej.