Czy blokowanie enumeracji użytkowników w WordPressie ma sens?

Blokowanie enumeracji użytkowników – czy to ma sens?

Enumeracja użytkowników WordPressa – brzmi dosyć dziko. Przekładając na zwykły język, chodzi o możliwość odkrycia loginów za pomocą podawania kolejnych liczb (najczęściej zaczynając od 1), które są identyfikatorami użytkowników w bazie danych. Do niedawna uważałem blokadę enumeracji jako podstawowy element bezpieczeństwa każdej nowej instalacji WordPressa…

Po co w ogóle enumerować?

Zwykłemu użytkownikowi strony raczej na nic się to nie przyda. Z reguły nie obchodzi go czy administrator ma przypisaną liczbę 1 czy 100 w bazie danych. Technika ta jest wykorzystywana w przypadku chęci uzyskania nieautoryzowanego dostępu do strony (w skrócie: do włamania się).

Mając login administratora możemy przeprowadzać atak metodą brute force. W dużym uproszczeniu atak ten polega na próbie zalogowania się z użyciem losowych haseł. Im prostsze hasło tym większa szansa na pomyślne zalogowanie. Im częściej używamy tego samego hasła w innych serwisach tym jeszcze większa szansa (skrypty najczęściej wykorzystują listę haseł z wycieków i innych szemranych źródeł). Jeśli nie posiadamy żadnych zabezpieczeń limitujących ilość prób logowania, to uparty „haker” może w końcu się włamać.

W jaki sposób enumerować?

Standardowa metoda

Każdy WordPress pozwala na dostanie się do archiwum wpisów autora za pomocą dwóch adresów:

  • http://adres-strony/author/uzytkownik
  • http://adres-strony/?author=identyfikator

Tym oto sposobem na moim blogu można wejść pod adres https://grabania.pl/?author=2 i zostanie się przekierowanym pod adres https://grabania.pl/autor/krzysztof/. Skrypty wykorzystywane do ataków najczęściej enumerują po początkowych liczbach (najczęściej do 10, ale przecież można sprawdzać ich nieskończenie wiele), później lecą szukać innych podatności.

Mając to na uwadze niektórzy mogli zwiększyć identyfikator pierwszego użytkownika np. do 10000 sądząc że to podniesie ich poziom bezpieczeństwa. Dzięki takiemu zabiegowi użytkownicy nie będą otrzymywać niskich identyfikatorów i trudniej będzie odkryć ich loginy za pomocą enumeracji. Na ich nieszczęście atakujący mają aktualnie lepszy sposób na odkrywanie użytkowników.

REST API

Od wersji 4.7, każdy blog postawiony na WordPressie posiada włączone REST API. Przez wielu znienawidzone ze względu na podatność w wersji 4.7.0, inni ciągle widzą w nim wielkie zło i wyłączają je na każdej ze swoich stron. Jednak ci, którzy nigdy o nim nie słyszeli lub go nie wyłączyli są narażeni na listowanie użytkowników. Wystarczy przejść pod adres http://adres-strony/wp-json/wp/v2-users/ (https://grabania.pl/wp-json/wp/v2/users/) aby poznać wszystkich użytkowników.

Odpowiedź z REST API WordPressa w formacie JSON zawierająca informacje o użytkowniku
Przykładowa odpowiedź z REST API

Jak się zabezpieczyć przed poznaniem mojego loginu?

W standardowym scenariuszu WordPressa nazwa użytkownika w adresie archiwum jest także jego loginem. Śmiało można zakładać, że wygląda to w ten sposób na większości witryn. Na szczęście nic nie stoi na przeszkodzie, aby zmienić pseudonim użytkownika.

W Edycji profilu (Użytkownicy > Twój profil na koncie administratora, Profil na koncie autora) istnieje pole tekstowe, w którym można wprowadzić dowolny pseudonim (przede wszystkim inny niż login).

Nazwa autora w adresie archiwum oraz slug w REST API są właśnie pseudonimem. Jego zmiana na inny niż nazwa użytkownika zabezpieczy nas najlepiej przed poznaniem loginu.

Pola tekstowe z ekranu Edycja profilu umożliwiające zmianę danych użytkownika, takich jak imię, nazwisko czy pseudonim.
Pole tekstowe zawierające pseudonim użytkownika

Czy warto zatem blokować enumerację?

Wszystko zależy od tego jacy są użytkownicy danej strony. Jeśli nie mamy kontroli nad tym czy użytkownik zmieni swój pseudonim czy nie, to mimo wszystko warto zabezpieczyć witrynę przed enumeracją.

RewriteCond %{QUERY_STRING} author=\d
RewriteRule ^ /? [L,R=301]

Blokowanie enumeracji użytkowników z wykorzystaniem .htaccess
Źródło: http://wpmagus.pl/pliki/prezentacje/wyczaruj-sobie-spokoj/#/29

Niestety to nie jedyna blokada, którą musimy nałożyć. Konieczne będzie wyłączenie także listowania użytkowników w REST API. W erze wchodzącego Gutenberga, który opiera się w pełni na REST API, jest to raczej niezbyt rozsądna opcja. Co więcej, Gutenberg korzysta z tego punktu w API, więc narażamy się na niestabilne działanie nowego edytora.

add_filter('rest_endpoints', 'disable_rest_api_users_endpoints');

function disable_rest_api_users_endpoints($endpoints)
{
    foreach ($endpoints as $endpoint => $tmp) {
        if (strpos($endpoint, '/wp/v2/users') !== false) {
            unset($endpoints[$endpoint]);
        }
    }

    return $endpoints;
}

Pozostaje jeszcze kwestia archiwów autorów, do których można przejść bezpośrednio spod każdego wpisu na stronie. O ile konta publikujące wpisy nie mają uprawnień administratora to nie ma co się martwić (najwyżej trzeba będzie przywrócić stronę z backupu). Można wyłączyć archiwa użytkowników (np. poprzez wtyczkę Yoast SEO), ale odnośniki pod wpisami nadal pozostaną, więc trzeba zedytować także motyw.

Osobiście uważam, że blokada enumeracji nie ma większego sensu. Mechanizmy wbudowane w WordPressa pozwalają w wystarczająco skuteczny sposób na ukrycie loginu użytkownika. Zdecydowanie lepiej jest wyedukować osoby zajmujące się moderacją kont na temat bezpieczeństwa w zakresie tworzenia użytkowników.

Podsumowanie: co zamiast blokady enumeracji i REST API?

Przede wszystkim zmiana pseudonimu użytkownika na inny niż login. To najprostsze, a za razem najlepsze co można zrobić. Nie ma pewniejszej metody na ukrycie loginu użytkownika niż ta.

Po drugie dwuetapowa weryfikacja konta (2FA – Two Factor Authentication). Nawet jeśli ktoś już pozna login i hasło, to i tak bez drugiego środka uwierzytelniającego nie zaloguje się. Istnieje masa wtyczek do tego, osobiście zalecam stosowanie wtyczki Two-Factor. Jest to wtyczka rozwijana w programie beta wtyczek, co oznacza że może zostać wchłonięta do Core WordPressa (czyt. może być domyślnie w każdym WordPressie).

Po trzecie wtyczka ograniczająca ilość błędnych prób logowania. Osobiście przetestowałem wtyczkę Limit Login Attempts, która pomimo braku aktualizacji przez ostatnie 6 lat (!) nadal spełnia swoje zadanie i działa bardzo dobrze.

Na sam koniec lista przydatnych artykułów na temat dodatkowego zabezpieczania WordPressa:


Autorem obrazka wyróżniającego jest Paul Bergmeir z serwisu Unsplash.

Autor

Krzysztof Grabania

Programista z zawodu oraz z zamiłowania. Na co dzień pracuje z Laravelem, WordPressem i Vue.js. Nie boi się poznawać nowych technologii i narzędzi. W wolnych chwilach tłumaczy WordPressa i jego wtyczki na język polski. Amator elektroniki oraz Raspberry Pi.