ARK. B11Parametr monitoringuBezpieczeństwo · lista 50 parametrów

REST API: enumeracja użytkowników

ważność wysokamierzonysposób exposure

Czy /wp-json/wp/v2/users albo ?rest_route= ujawnia listę loginów. Atakujący zna połowę danych do brute-force konta admina.

ARK. 1

WIKI

artykuł z 16.09.2026 · źródeł 10

REST API: enumeracja użytkowników to parametr monitoringu stron WordPress, który sprawdza, czy anonimowy klient może z zewnątrz poznać identyfikatory kont: z listy użytkowników w REST API albo z przekierowania na archiwum autora. Pomiar kończy się jednym z trzech wyników: identyfikatory ujawnione, nieujawnione albo brak odpowiedzi w wyznaczonym czasie. Trasa /wp/v2/users REST API WordPressa zwraca rekordy użytkowników z polami takimi jak id, name, slug, link i avatar_urls [1].

Jak działa

Pola rekordu użytkownika są przypisane do kontekstów. W domyślnym kontekście view widać m.in. id, name, url, description, link i slug, a login (username), adres e-mail i role należą wyłącznie do kontekstu edit [1]. Kontroler odrzuca kontekst edit, jeśli klient nie ma uprawnienia list_users, a takim klientom zawęża listę do osób z opublikowanymi wpisami w typach treści dostępnych przez REST [4]. Lista ma domyślnie 10 rekordów na stronę [1].

Pole slug to wartość user_nicename [4]. Jeśli przy zakładaniu konta nie podano jej osobno, WordPress bierze pierwsze 50 znaków loginu i przepuszcza je przez sanitize_title [6]. Slug jest więc zwykle loginem zapisanym w postaci nadającej się do adresu, ale może się od niego różnić.

Do tej samej trasy prowadzą dwie ścieżki. Na stronach bez przyjaznych odnośników trasa trafia do parametru rest_route, np. ?rest_route=/wp/v2/posts/123 [2]. Kod rdzenia rejestruje rest_route jako zmienną zapytania, a adresy zaczynające się od /wp-json/ przepisuje regułami na index.php?rest_route= [3]. Zablokowanie samej ścieżki /wp-json/ nie zamyka zatem parametru.

Trzecia droga nie korzysta z REST. Gdy żądanie strony ma liczbowy parametr author, a użytkownik o tym numerze ma choć jeden opublikowany wpis, funkcja kanonicznych przekierowań odsyła klienta na adres archiwum autora zbudowany z user_nicename [5]. Podstawiając kolejne liczby, można w ten sposób odczytać slug każdego autora.

RYS. 1.1Trzy drogi do identyfikatora konta

Standardy i specyfikacje

  • REST API Handbook, Users definiuje pola rekordu, ich konteksty i parametry listy, w tym per_page i has_published_posts [1].
  • Core Contributor Handbook, FAQ bezpieczeństwa stwierdza, że projekt WordPress nie uważa nazw użytkowników ani ich numerów za prywatne: login ma identyfikować, a weryfikacja jest zadaniem hasła [7]. Publiczny dostęp do listy przez GET /wp-json/wp/v2/users jest według tego dokumentu zamierzony [7]. WordPress pozwala logować się loginem albo adresem e-mail i zamiast ukrywać identyfikator zachęca do silnych haseł [7].
  • OWASP WSTG-IDNT-04 każe sprawdzić, czy da się zebrać listę prawidłowych nazw użytkowników, bo przydaje się ona w ataku siłowym albo przy próbach domyślnych haseł [8]. Przewodnik zaznacza, że część aplikacji nie traktuje nazw użytkowników jako wrażliwych i celowo je wyświetla, więc przed zgłoszeniem trzeba znać wymagania aplikacji [8]. Wśród zaleceń wymienia jednolite komunikaty błędów logowania i usuwanie kont domyślnych oraz testowych przed wdrożeniem [8].

Zagrożenia i skutki

Połowa danych logowania. Lista kont pozwala skupić próby haseł na istniejących identyfikatorach zamiast zgadywać także nazwę [8]. Stanowisko WordPressa przenosi ciężar ochrony na hasło [7], więc realne ryzyko zależy od siły haseł i od tego, czy slug pokrywa się z loginem [6].

RYS. 1.2Od identyfikatora do przejęcia konta

Pusta lista nie oznacza braku kont. Anonimowy klient widzi tylko autorów opublikowanych wpisów [4], a przekierowanie z ?author= działa tylko dla użytkownika z opublikowanym wpisem [5]. Administrator, który niczego nie publikuje, nie pojawi się żadną z tych dróg.

Blokada jednej ścieżki. Reguła odmawiająca dostępu do /wp-json/ nie obejmuje żądania z parametrem rest_route, bo obie drogi kończą się w tej samej obsłudze zmiennej zapytania [3].

Przykłady

Dokumentacja REST API odradza wyłączanie całego interfejsu, bo przestają wtedy działać funkcje panelu administracyjnego; zamiast tego pozwala wymagać uwierzytelnienia filtrem rest_authentication_errors ze sprawdzeniem is_user_logged_in [10]. Węższym narzędziem jest filtr rest_endpoints (od wersji 4.4.0), który filtruje tablicę dostępnych tras REST API i pozwala usunąć z niej trasy użytkowników [9]. Po stronie archiwum autora przekierowanie przechodzi przez filtr redirect_canonical, a zwrócenie z niego false anuluje przekierowanie [5].

Żądanie lub ustawienieOdpowiedźCo ujawnia
GET /wp-json/wp/v2/users bez logowania [1] [4]200 z listą autorów wpisówid, name, slug, link
GET /wp-json/wp/v2/users?context=edit bez uprawnień [4]odmowalogin, e-mail i role pozostają ukryte
GET /?rest_route=/wp/v2/users przy blokadzie /wp-json/ [2] [3]200 z tą samą listąslug
GET /?author=1, autor z opublikowanym wpisem [5]przekierowanie na archiwum autoraslug w adresie
GET /?author=1, konto bez wpisów [5]brak przekierowanianic
Filtr rest_endpoints usuwający trasy użytkowników [9]brak trasylista niedostępna
Filtr redirect_canonical zwracający false dla ?author= [5]brak przekierowaniaslug nie trafia do nagłówka Location
rest_authentication_errors z is_user_logged_in [10]błąd dla anonimowychcały REST tylko po zalogowaniu
TAB. 1.1Przypisy10
  1. [1] Users — REST API Handbook Reference · WordPress.org
  2. [2] Routes and Endpoints — REST API Handbook · WordPress.org
  3. [3] rest-api.php — rejestracja tras i reguł przepisywania REST API · WordPress
  4. [4] class-wp-rest-users-controller.php — kontroler /wp/v2/users · WordPress
  5. [5] canonical.php — funkcja redirect_canonical · WordPress
  6. [6] user.php — funkcja wp_insert_user · WordPress
  7. [7] Reporting Security Vulnerabilities — Core Contributor Handbook · WordPress.org
  8. [8] WSTG-IDNT-04 — Account Enumeration and Guessable User Account · OWASP Web Security Testing Guide
  9. [9] Hook rest_endpoints — Code Reference · WordPress.org
  10. [10] Frequently Asked Questions — REST API Handbook · WordPress.org
ARK. 2

STATS

wyniki z systemu · tylko liczby zbiorcze
TAB. 2.1Odczyty per strona

Ten parametr nie zapisuje odczytu per strona — przebieg zostawia tylko ustalenia, więc liczby sprawdzonych stron i wyników „ok” system nie ma. Pojawią się po wdrożeniu zapisu przebiegów per strona per parametr.

TAB. 2.3Ustaleniaod 24.07.2026
Otwarte teraz
10stron: 7
Nowe w ostatnim dniu
809.09.2026
Otwarte od początku
10stron: 7
Zamknięte
0od początku
Mediana trwania
od wykrycia do zamknięcia
UstalenieSkutekOtwarte terazŁącznieZamknięte
Enumeracja użytkowników exposure_users_enumPODATNA660
Login administratora z /?author=1 exposure_author_enumPODATNA440
RYS. 2.2Nowe ustalenia, 30 dni
23.08.202607.09.202621.09.2026
Nowe ustalenia parametru REST API: enumeracja użytkowników, 30 dni · wysokość słupka = liczba ustaleń dnia, warstwy od dołu: nowe ustalenia · dni bez odczytu: 29
Nowe ustalenia parametru REST API: enumeracja użytkowników, 30 dni
Dzieńnowe ustalenia
23.08.20260 ustaleń
24.08.20260 ustaleń
25.08.20260 ustaleń
26.08.20260 ustaleń
27.08.20260 ustaleń
28.08.20260 ustaleń
29.08.20260 ustaleń
30.08.20260 ustaleń
31.08.20260 ustaleń
01.09.20260 ustaleń
02.09.20260 ustaleń
03.09.20260 ustaleń
04.09.20260 ustaleń
05.09.20260 ustaleń
06.09.20260 ustaleń
07.09.20260 ustaleń
08.09.20260 ustaleń
09.09.20268 ustaleń
10.09.20260 ustaleń
11.09.20260 ustaleń
12.09.20260 ustaleń
13.09.20260 ustaleń
14.09.20260 ustaleń
15.09.20260 ustaleń
16.09.20260 ustaleń
17.09.20260 ustaleń
18.09.20260 ustaleń
19.09.20260 ustaleń
20.09.20260 ustaleń
21.09.20260 ustaleń
TAB. 2.4Przebiegi z tym sposobem sprawdzeniaod 09.09.2026
Przebiegów
33sposób exposure
W 30 dni
33przebiegów
Ostatni
19.09.2026start przebiegu
Stron w przebiegach
33 przebiegów bez liczby stron
ARK. 3

CARD

karta z kodu CREATO_PING, odczyt 16.09.2026
RYS. 3.1Droga parametru przez system: REST API: enumeracja użytkowników
TAB. 3.1Pomiarpliki: 5
Obszar i ważnośćBezpieczeństwo · wysoka (B11)
Workflow i częstotliwośćcreato_ping_security_v2 · P3 działa na LAB247cron co 24 h, T1–T3; T4 raz po anomalii · Dokładny skan. dns_integrity porównuje NS, MX, SPF i DMARC z wzorcem z poprzedniego przebiegu.
Sonda i helpersposób exposure · CREATO_PING/helpers/exposure_check.py
Testy
  1. Tylko przebieg P3; przed sondami strażnik losowej ścieżki (200 z treścią = sondy pominięte).
  2. GET /?rest_route=/wp/v2/users&per_page=100 i /wp-json/wp/v2/users bez podążania za przekierowaniami; reguła: kod 200, treść zaczyna się od [ i zawiera pole slug. Trafienia obu ścieżek sklejane w jedno ustalenie.
  3. GET /?author=1 bez podążania za przekierowaniem; reguła: kod 3xx i nagłówek Location z /author/ i segmentem po nim.
Typ wyniku0 do 2 ustaleń: exposure_users_enum (REST) i exposure_author_enum (przekierowanie autora)
Jednostkabrak — wynik jakościowy; w dowodzie liczba i pierwsze trzy slugi kont albo slug z przekierowania
Próg i regułaTimeout odpowiedzi 15 s, połączenia 5 s. 401, 403, 404, pusta tablica, błąd sieci i timeout = brak ustalenia.
Gdzie leżą pokrętłaCREATO_PING/helpers/exposure_check.py → PROBES (json_users, author_redirect), _AUTHOR_LOCATION, _REDIRECT_CODESCREATO_PING/helpers/config.py → TIMEOUTS["exposure"], TIMEOUTS["security_connect"]CREATO_PING/helpers/security_runner.py → _TASK_SEVERITIESCREATO_PING/config/incident_policy.toml → [finding] exposure_users_enum, exposure_author_enum
Retencja odczytówOdczytu per strona nie zapisujemy — zostaje tylko ustalenie w tabeli findings (otwarcie, zamknięcie, dowód). Replay po surowych odczytach dziś niemożliwy.
Znane rozbieżności
  1. Dowód podpisuje jako login wartość, która jest slugiem (user_nicename): REST bez logowania nie zwraca loginu. Slug zwykle pochodzi z loginu, ale może się od niego różnić.
  2. Ustalenie wysokie powstaje na domyślnej instalacji WordPressa z choć jednym opublikowanym wpisem — rdzeń uznaje tę listę za publiczną z założenia, więc PODATNA obejmuje każdą stronę bez utwardzenia.
  3. Pusta lista nie znaczy „loginy ukryte”: anonimowy klient widzi tylko autorów opublikowanych wpisów — administrator bez wpisów jest niewidoczny na wszystkich trzech drogach.
  4. Sondowany jest tylko numer konta 1; inne numery nie są próbowane.
  5. Liczba kont w dowodzie jest zaniżona: liczone są slugi w pierwszych 5000 znaków, a ścieżka /wp-json/ pyta tylko o 10 rekordów.
  6. alert w polityce nie jest czytany, brak trzeciego stanu i brak sygnału zamknięcia — wspólne dla sond ekspozycji.
kandydaci do pętli: kod a opis parametru albo specyfikacja
Karta przepisana zCREATO_PING/helpers/exposure_check.py · CREATO_PING/helpers/config.py · CREATO_PING/config/incident_policy.toml · CREATO_PING/helpers/security_runner.py · CREATO_PING/helpers/clickup_writer_v2.py · odczyt 16.09.2026
TAB. 3.2Co oznacza failtypów ustaleń: 2

Oba typy: powaga wysoka, pewność ewidentna, skutek PODATNA — do dwóch osobnych subtasków z priorytetem wysokim, status strony przeliczony na PODATNA.

UstaleniePowagaPewnośćSkutekSubtask / alarmCo zrobić
Enumeracja użytkownikówexposure_users_enumWysokieEwidentnePODATNAtak / nieZablokuj /wp-json/wp/v2/users i ?author=N.
Login administratora z /?author=1exposure_author_enumWysokieEwidentnePODATNAtak / nieZablokuj przekierowanie ?author=N (reguła serwera albo wtyczka bezpieczeństwa).
ARK. 4

LOOP

pętli: 3
RYS. 4.1Pętla parametru — sześć etapów
TAB. 4.1Trafność, 30 dnialarmy · prawdziwe · fałszywe · bez rozstrzygnięcia

Trafności jeszcze nie liczymy: zamknięcie subtaska nie niesie dziś werdyktu (prawdziwy / fałszywy / nie dało się sprawdzić). Cztery liczby pojawią się, gdy każde zamknięcie dostanie werdykt — to warunek startu pętli 1.

TAB. 4.2Pętle3 · zmian: 5 · wpływających na cały system: 3
Strażnik losowej ścieżki i dłuższy limit czasu dla sond ekspozycjizamknięta historyczna 2026-09-05

Sygnał: Tarcze antybotowe hostingu, strony parkingowe i serwery catch-all odpowiadają 200 na każdą ścieżkę, więc sondy oparte na kodzie 200 dawały „wystawiony” wszędzie. Równocześnie sondy na wolnych hostingach odpowiadały po około 15 s, a limit 5 s ucinał je bez śladu. · dotyczy też: Ekspozycja .env, Ekspozycja plików wrażliwych, Ekspozycja .htaccess.bak, Dostępność xmlrpc.php, Ekspozycja .git/HEAD, Dostępność readme.html, Dostępność wp-cron.php, Ekspozycja kopii zapasowych, Ekspozycja zrzutu bazy, Ekspozycja manifestów dev, Ekspozycja .DS_Store

  1. 1. Zbiórkaręcznieodczyt z nocnego skanu, bez zapisu per strona
  2. 2. Werdyktręcznieprzegląd skanera: 200 na wszystko i ciche timeouty to fałszywe wyniki
  3. 3. Miarabrakliczników trafności wtedy nie było
  4. 4. Kartabrakkarta parametru powstała 2026-09-16
  5. 5. Zmianazrobionestrażnik ścieżki, 15 s, logowanie błędów
  6. 6. Replaybrakbrak zapisanych odczytów do replayu
DataZmianaPowódWpływ na systemCommit · replay
2026-09-05Przed sondami GET losowej, nieistniejącej ścieżki; odpowiedź 200 z treścią = zero sond i jedno ustalenie exposure_scan_unreliable (niska powaga, bez subtaska).helpers/exposure_check.py · config/incident_policy.tomlOdpowiedź 200 na losową ścieżkę dowodzi, że kod 200 na tym serwerze nic nie znaczy; dalsze sondowanie tarczy grozi banem IP monitoringu.cały system Obejmuje wszystkie sondy ekspozycji naraz i wprowadza typ „nie dało się sprawdzić”; tę samą konwencję dostało wykrywanie wtyczek. Ustalenie ma niską powagę, więc filtr przebiegu je odrzuca i w produkcji nie zostawia śladu.b0fc77cbez replayubez zapisu zatwierdzenia
2026-09-05Limit odpowiedzi z 5 s na 15 s i połączenia z 2 s na 5 s, przeniesione do config.py; błąd sieci sondy logowany zamiast cichego pustego wyniku; do 4 sond naraz na stronę.helpers/config.py · helpers/exposure_check.py · helpers/html_fetch.py · helpers/wp_fingerprint.pyWolne hostingi odpowiadały po około 15 s, a pusty wynik po timeoucie był nieodróżnialny od „sprawdzone, czysto”.cały system Limit połączenia 5 s przejęło wspólne pobieranie HTML całego skanu bezpieczeństwa i wykrywanie wersji — strony z wolnym TLS przestały wypadać z całego skanu.b0fc77cbez replayubez zapisu zatwierdzenia
Limit 64 KB czytanej odpowiedzi po awarii pamięcizamknięta historyczna 2026-07-19

Sygnał: Brak pamięci podczas skanu: publiczny debug.log jednej ze stron był bardzo duży, a klient HTTP buforował całą odpowiedź. · dotyczy też: Sitemap.xml, Ekspozycja plików wrażliwych, Ekspozycja .env, Ekspozycja .htaccess.bak, Dostępność xmlrpc.php, Ekspozycja .git/HEAD, Dostępność readme.html, Dostępność wp-cron.php, Ekspozycja kopii zapasowych, Ekspozycja zrzutu bazy, Ekspozycja manifestów dev, Ekspozycja .DS_Store

  1. 1. Zbiórkaręcznieodczyt z nocnego skanu, bez zapisu per strona
  2. 2. Werdyktręcznieawaria procesu przypisana ścieżce debug.log
  3. 3. Miarabrakliczników trafności wtedy nie było
  4. 4. Kartabrakkarta parametru powstała 2026-09-16
  5. 5. Zmianazrobionestrumień z limitem 64 KB
  6. 6. Replaybrakbrak zapisanych odczytów do replayu
DataZmianaPowódWpływ na systemCommit · replay
2026-07-19Odpowiedź sondy czytana strumieniem do 64 KB; do oceny idzie pierwsze 5000 znaków.helpers/exposure_check.py · helpers/html_fetch.py · helpers/sitemap_check.pyDo rozpoznania ekspozycji wystarcza początek pliku; zmiana dotyczy sposobu czytania, nie werdyktu.cały system Brak pamięci w helperze zatrzymywał cały proces skanu bezpieczeństwa partii stron; ten sam limit dostało sprawdzenie sitemap.343b699bez replayubez zapisu zatwierdzenia
Enumeracja użytkowników także przez ?rest_route= i /?author=1zamknięta historyczna 2026-09-05

Sygnał: Blokada /wp-json/ na poziomie WAF-a dawała „czysto”, choć ta sama lista kont była dostępna przez /?rest_route=/wp/v2/users, a login administratora zdradzało przekierowanie /?author=1.

  1. 1. Zbiórkaręcznieodczyt z nocnego skanu, bez zapisu per strona
  2. 2. Werdyktręcznieprzegląd skanera: blokada jednej ścieżki nie zamyka enumeracji
  3. 3. Miarabrakliczników trafności wtedy nie było
  4. 4. Kartabrakkarta parametru powstała 2026-09-16
  5. 5. Zmianazrobionedwie dodatkowe drogi enumeracji
  6. 6. Replaybrakbrak zapisanych odczytów do replayu
DataZmianaPowódWpływ na systemCommit · replay
2026-09-05Sonda /?rest_route=/wp/v2/users obok /wp-json/wp/v2/users; trafienia sklejane w jedno ustalenie, w dowodzie liczba kont i trzy pierwsze loginy.helpers/exposure_check.pyParametr rest_route omija blokadę samej ścieżki /wp-json/.tylko ten parametrb0fc77cbez replayubez zapisu zatwierdzenia
2026-09-05Sonda /?author=1 bez podążania za przekierowaniem: 3xx na /author/<login>/ = ustalenie exposure_author_enum (wysoka powaga, subtask PODATNA).helpers/exposure_check.py · config/incident_policy.tomlLogin administratora wycieka przekierowaniem nawet wtedy, gdy REST jest zablokowany.tylko ten parametrb0fc77cbez replayubez zapisu zatwierdzenia
Blog 24/7
20.09Zastrzeżony PESEL: zmiana raz na 30 minut, blokada przy wypłaciedobreprogramy.pl20.09Fałszywe SMS-y od GITD o mandacie za autostradę wyłudzają dane kartyinstalki.pl20.09Pakiet npm indexed-btree omija blokadę skryptów instalacyjnychbleepingcomputer.com19.09SolarWinds łata CVE-2026-28326 w Access Rights Manager, zdalny kod bez logowaniathehackernews.com19.09Orkes Conductor: luka CVE-2026-58138 atakowana w sieci, poprawka w wersji 3.30.2thehackernews.com19.09Trzy luki jądra Linux w katalogu CISA KEV, Red Hat potwierdza aktywne atakithehackernews.com18.09Publiczne exploity na cztery luki jądra Linux dają lokalnie uprawnienia rootthehackernews.com18.09Brevo: skradziony klucz API Cloudflare i skrypty ClickFix na stronach klientówbleepingcomputer.com18.09WaterPlum z Korei Północnej zainfekowała 30 000 urządzeń w 100 krajachtherecord.media18.09Jedna zgoda OAuth daje napastnikowi dostęp do poczty i plików mimo MFAdarkreading.com