203 trasy: co API REST WordPressa wydaje bez logowania

Spis treści
Witryna na WordPressie udostępnia zarówno strony wyświetlane przez przeglądarkę, jak i interfejs zwracający same dane. Ten interfejs jest włączony od pierwszej minuty, choć osoby prowadzące witrynę rzadko go sprawdzają.
Leży pod /wp-json/, a jego pierwsza odpowiedź to lista wszystkiego, co potrafi.

Po co jest ten interfejs
API REST istnieje po to, by ze stroną mogło pracować coś innego niż przeglądarka: edytor bloków w panelu, aplikacja w telefonie, inna strona przejmująca artykuły, skrypt publikujący według planu.
Należy do samego WordPressa, nie jest wtyczką, i odpowiada domyślnie od 2016 roku. Niczego nie trzeba włączać.
Wniosek wart zapamiętania: co opublikowane na stronie, jest opublikowane także tutaj, w postaci przeznaczonej dla maszyn. Nie kopia i nie streszczenie – ta sama treść, znacznie łatwiejsza do zebrania.
203 trasy na zwyczajnej stronie
Spis pod /wp-json/ odpowiedział na mierzonej tutaj stronie 203 trasami w dziewięciu przestrzeniach nazw.
110 z nich należy do wp/v2, czyli rdzenia: wpisy, strony, media, komentarze, kategorie, tagi, typy bloków i reszta standardowego wyposażenia.
59 należy do jednej wtyczki. To ponad jedna czwarta całego interfejsu z jednego rozszerzenia, a niezwykłe to nie jest – duża wtyczka chętnie rejestruje osobną trasę dla każdego swojego widoku.
Pozostałe 34 rozkładają się na siedem przestrzeni nazw, w większości po trzy do ośmiu tras.
Lista przestrzeni nazw jest listą wtyczek
Spis nie tylko liczy trasy. Nazywa przestrzenie nazw, a przestrzeń nazw wybiera ten, kto wtyczkę napisał.
W odpowiedzi na jedno zapytanie bez logowania stoi zatem otwartym tekstem, jakie wtyczki są zainstalowane: wtyczka SEO, wtyczka wielojęzyczna, wtyczka do bloków kodu i każdy własny kod, który strona rejestruje dla siebie.
Wyciekiem w sensie usterki to nie jest. Tak musi działać interfejs, bo program musi wiedzieć, co jest dostępne. Znaczy to jednak, że pytanie „jakie wtyczki działają na tej stronie” ma odpowiedź w jednym zapytaniu – a tej odpowiedzi używa się regularnie, by sprawdzić, które wersje mają znane słabości.

Co odpowiada bez logowania
Czytanie jest w dużej mierze otwarte, co wynika z tego, że treści i tak są publiczne.
Wpisy, strony, komentarze, kategorie, tagi, typy wpisów, media oraz trasy wtyczki SEO i wielojęzycznej odpowiedziały statusem 200 i prawdziwą treścią.
Jeden szczegół zasługuje na chwilę uwagi. Zapytanie o pojedynczy wpis zwróciło 23 455 bajtów: cały, gotowo złożony artykuł, nie fragment. Wszystko opublikowane leży gotowe po jednym zapytaniu na wpis, czysto rozdzielone na pola, bez tej otoczki, którą dźwiga strona.
Co żąda logowania i która odmowa jest lepsza
Wszystko, co opisuje instalację zamiast treści, zażądało logowania: ustawienia, lista wtyczek, lista motywów, typy bloków, diagnostyka systemu. Wszystkie odpowiedziały 401.
Jedna trasa odpowiedziała inaczej i właśnie ona nadaje się do naśladowania: wp/v2/users zwróciła 404.
Różnica nie jest kosmetyczna. 401 albo 403 potwierdza, że trasa jest i jest pilnowana – mówi więc, że kryje się za nią coś prawdziwego, dla czego opłaca się druga próba. 404 nie mówi nic. Trasę usunięto zamiast chronić, a z zewnątrz nie da się tego odróżnić od WordPressa, który nigdy jej nie oferował.
Nazwiska autorów są zwykłym powodem tej odmowy. Stanowią połowę logowania, a ich publiczna lista jest publiczną listą ważnych nazw użytkowników.
Co warto sprawdzić
Trzy pytania odpowiadają sobie same, po jednym zapytaniu każde.
Co wymienia /wp-json/? Które przestrzenie nazw się pojawiają i czy któraś należy do czegoś, co nie jest już używane? Wyłączona wtyczka nie rejestruje nic; aktywna, ale zapomniana rejestruje wszystko, co ma.
Co odpowiada /wp-json/wp/v2/users? 200 wydaje nazwiska autorów. 401 potwierdza, że istnieją. 404 nie mówi nic.
I co wraca dla pojedynczego wpisu? Jeśli odpowiedzią jest cały artykuł, interfejs działa dokładnie tak, jak zaprojektowano – warto jednak wiedzieć, że treść jest dostępna również w tej postaci, nie tylko jako strona.
Te same dwa pytania, ile tras wymienia /wp-json/ i co odpowiada wp/v2/users, zostały zadane także dwunastu instalacjom; wyniki, od 203 do 1107 tras, zawiera artykuł 1107 tras bez logowania: co dziesięć instalacji WordPressa wydaje pod /wp-json/.
Pytania i odpowiedzi
Czy wystarczy usunąć wp/v2/users, żeby nazwy użytkowników przestały wyciekać?
Nie, ta trasa jest tylko najwygodniejszą listą. W ustawieniach domyślnych to samo zdradzają jeszcze dwa miejsca:
- Archiwum autora. W przypadku autorów z opublikowanymi wpisami adres taki jak /?author=1 przekierowuje na /author/<slug>/, a ten slug WordPress wyprowadza przy zakładaniu użytkownika z nazwy logowania. Sprawdzenie kolejnych numerów daje w zasadzie tę samą listę.
- Interfejs oEmbed pod /wp-json/oembed/1.0/. Do każdego wpisu zwraca wyświetlaną nazwę autora i adres jego archiwum, razem ze slugiem.
Wyświetlana nazwa w kanałach RSS i pod wpisami nie stanowi problemu, dopóki różni się od nazwy logowania. Trwałe rozwiązanie leży więc nie tyle w ukrywaniu, ile w nazwie logowania, która nigdzie publicznie się nie pojawia, i w logowaniu, przy którym sama nazwa na nic się nie zda, na przykład dzięki silnemu hasłu i uwierzytelnianiu dwuskładnikowemu.
Czy strona zdradza swoje wtyczki także bez spisu pod /wp-json/?
Zwykle tak. Arkusze stylów i skrypty wtyczki leżą pod /wp-content/plugins/ w folderze nazwanym zazwyczaj tak jak wtyczka i często niosą numer wersji w parametrze ver. Ukrycie spisu usuwa więc jedno źródło, a nie samą informację.