Nie używasz REST API? To go wyłącz!

WordPress REST API

WordPress 4.7 wprowadził pełne REST API, poprzez które zewnętrzne aplikacje czy usługi mogą odczytywać wszystkie treści dostępne publicznie na naszej stronie, a po autoryzacji również je modyfikować i dodawać nowe. Idea tego interfejsu jest świetna i osobiście jestem jej wielkim zwolennikiem, ponieważ daje ona ogromne możliwości, dzięki którym WordPress może być wykorzystywany nie tylko do tworzenia stron, ale również jako CMS dla aplikacji mobilnych czy magazyn treści dla zewnętrznych serwisów i usług.

Interfejs ten ma jednak jedną wadę: każdy może z niego skorzystać, a domyślnie jest on włączony. Tak więc jeśli go nie używamy, to najlepiej po prostu go wyłączyć.

Wszystkie nasze treści dostępne dla każdego

Jak już wiemy, nie sposób zabezpieczyć naszych treści przed złodziejami – jeśli ktoś chce, to wyciągnie z naszej strony wszystko. W Internecie działa mnóstwo stron, które agregują treści bez wiedzy i zgody ich autorów. Pomijając sensowność tego procederu (Google jest coraz lepszy w rozpoznawaniu takich stron), nie jest to coś, co osoby poświęcające wiele godzin na tworzenie treści chciałyby widzieć.

Skrypty wyciągające teksty ze stron korzystają najczęściej z kanałów RSS. Oczywiście łatwo jest w ustawieniach WordPressa skonfigurować je tak, aby zawierały tylko fragmenty wpisów. W takim przypadku większość automatów daje sobie spokój, bo parsowanie strony w celu wyciągnięcia z niej treści wpisu jest już większym problemem.

Jednak niezależnie od ustawień kanałów RSS, REST API zawsze udostępnia całą treść wpisów. Aby to zobaczyć wystarczy w przeglądarce wpisać adres odpowiedniej metody API: http://nasza-domena.pl/wp-json/wp/v2/posts/ (działający przykład). To daje automatom do wyciągania treści ze stron możliwość szybkiego i taniego (zużywającego mało zasobów serwera) pobierania naszych wpisów.

Wszystko to dotyczy nie tylko wpisów, ale również stron, multimediów i komentarzy.

Pobieranie listy użytkowników

REST API udostępnia też metodę zwracającą listę wszystkich aktywnych użytkowników naszej strony. Mimo że lista ta nie zawiera oczywiście haseł ani adresów e-mail, to sam fakt jej dostępności jest już lekkim ułatwieniem dla złośliwych skryptów próbujących łamać hasła metodą brute force.

Jak wyłączyć REST API?

Przede wszystkim warto zaznaczyć, że nie ma tu żadnych powodów do paniki. Wszystkie dane udostępniane przez REST API są i tak w takiej czy innej formie dostępne na naszej stronie. Jednak jeśli nie korzystamy z REST API, to osobiście polecałbym jego wyłączenie.

Najprostszym sposobem na wyłączenie REST API jest dodanie takiego kodu do pliku functions.php motywu lub do pliku wtyczki:

Można też skorzystać z darmowej wtyczki REST API Toolbox, która pozwala nie tylko na wyłączenie całego REST API, ale również pojedynczych metod, dzięki czemu możemy na przykład wyłączyć możliwość pobierania wpisów, ale zostawić dostęp do komentarzy czy stron.

REST API Toolbox

Po instalacji i aktywacji wtyczki wystarczy w panelu administracyjnym przejść do sekcji Ustawienia → REST API Toolbox i na zakładce General wyłączyć REST API i wsparcie dla JSONP. Jeśli chcemy wyłączyć tylko wybrane metody API, możemy to zrobić na zakładce Core.

Bezpośredni link

  • Czyli dzięki RestAPI mogę stronę A karmić treścią ze strony B?
    A jak w takim przypadku zmusić stronę A do aktualizacji treści, jeśli ona została zmieniona na stronie B?

    A da się ograniczyć RestAPI tak, by tylko strona A (np jej IP) mogło z niego korzystać? Np. wykorzystując .htaccess?

    • Tak, możesz.
      Niestety, musisz sobie wymyślić jakiś mechanizm aktualizacji. Albo strona A może okresowo sprawdzać dane na stronie B (data modyfikacji), albo strona B może powiadamiać stronę A, że jakaś treść się zmieniła.

      Da się w .htaccess – REST API ma swój własny URL.

      • Mówisz o pingach? Iż strona B pinguje stronę A o zmianie?

        Szczerze, to ja myślałem o jakieś sitemap, która by miała jakieś timestemp i dzięki czemu strona A wiedziała co ma starego. Takie rozwiązanie jest dla mnie o tyle korzystne, iż strona A i B, to nie mają być kopie 1:1, ale po prostu pewne materiały powinny na stronie A powinny być zawsze aktualne względem strony B.

        • Mogą być pingi, może być jakiś własny mechanizm, który będzie uwzględniał tylko aktualizacje treści, które zostały pobrane na stronę A. Generalnie brzmi to jak jakieś specyficzne rozwiązanie, a to wymaga specyficznych rozwiązań. ;) Tak czy inaczej sam mechanizm REST API powinien się tutaj sprawdzić, tym bardziej, że bardzo łatwo możesz sobie stworzyć własne metody (np. do powiadamiania drugiej strony o aktualizacjach treści).

  • A jeszcze pytanie o „stronę bezpieczeństwa” czy można zrobić kopię strony (1:1) z wykorzystaniem RestAPI, tak by edycja na stronie Z, nie obciążała strony K. I w drugą stronę, by duży ruch na K (np DDoS) nie utrudniał pracy na zapleczu (Z)?

    • Wszystko zależy od tego, jak taka „kopia” miałaby działać. Jeśli edycja strony A ma zrobić aktualizację przez API na stronie B, to obciążenie będzie mniejsze (a w najgorszym razie podobne) do tego, jakie zrobiłbyś aktualizując stronę B przez panel administracyjny. Z kolei DDoS na stronie B nie powinien w ogóle ruszać API na stronie A – chyba że strona A przy każdej odsłonie pobierane dane z API strony B (to dość powszechna praktyka – ale tutaj wchodzi już w grę cache po stronie serwera na stronie B).

      Generalnie temat jest dość złożony, tym bardziej, że nie zdradziłeś zbyt wiele na temat tego, jak to wszystko ma działać i jaki cel chcesz osiągnąć. ;)

  • ideagrafika

    A jakie ryzyko niesie za sobą nie wyłączenie tej wtyczki? Chodzi tylko o ataki? Czy domyślnie włączona ale nie używana funkcja zużywa nam jakieś zasoby serwera?

    • To nie niesie za soba ryzyka ataku. Tu raczej chodzi o udostępnienie danych, których niekoniecznie chcemy w ten sposób udostępniać. Samo REST API nie zużywa zasobów serwera, ale oczywiście może zacząć jeśli ktoś odpowiednio intensywnie zacznie się do niego dobijać.

  • Czy po wyłączeniu ResetAPI wtyczką REST API Toolbox mogę ją usunąć i funkcja ta będzie nadal wyłączona? Po co zapychać zasoby kolejną wtyczką.

  • Czy wyłączenie o którym tutaj piszesz zabezpieczyło by przed atakiem o którym pisałeś w https://wpzen.pl/wnioski-z-atakow-wykorzystujacych-ostatnia-luke-bezpieczenstwa-w-wordpressie/ ? Czy z punktu widzenia optymalizacji liczby wtyczek lepiej zastosować kod który podałeś, czy nie ma to znaczenia?

    • Tak, wyłączenie REST API zabezpieczyłoby stronę przed tym atakiem, bo niezależnie od wybranego sposobu wyłączenie następuje zanim API zrobi cokolwiek.

      Jesli chodzi o wydajność, to nie ma to większego znaczenia. Wybierz to, czego potrzebujesz: jeśli chcesz całkowicie (ale serio całkowicie ;)) wyłączyć REST API, to możesz użyć mojego kodu; jeśli chcesz mieć nad tym większą kontrolę, to użyj wtyczki.

      • Coś sknociłem w dodawaniu tego kawałka kodu do pliku – „Najprostszym sposobem na wyłączenie REST API jest dodanie takiego kodu do pliku functions.php motywu” – rozumiem, że chodzi o plik motywu- „wp-content/themes/[nazwa motywu]/functions.php. Dodałem sobie to tak – https://uploads.disquscdn.com/images/a76c186816e7ab0df88d577c70656c4b4a89ead8c74d625a9e3f5fa55990559a.png i pojawił mi się problem tego typu – https://uploads.disquscdn.com/images/baffde2cadd6d84ad7778c3f268f360197dc506f347008ca49b60c2d7fffc37b.png
        Proszę o podpowiedź jak powinno to poprawnie zostać dodane.

        • Kod został dodany poprawnie, tyle że wtyczka Contact Form 7 korzysta z REST API, tak więc nie możesz go całkowicie wyłączyć. Skorzystaj z wtyczki REST API Toolbox, dzięki której będziesz mógł zostawić niezbędne do działania wtyczki funkcje.

          • Paweł Knapek

            Tylko w chwili obecnej niezbędny wydaje się całkowity brak autoryzacji, więc zabawa w blokady traci sens.
            Problem komunikowany już na forum wtyczki. A do czasu wyjścia poprawionej wersji wielu woli się cofnąć do działającej wersji 4.7 wtyczki, niż otwierać całkowicie RESTa.

          • Jesteś pewien? Mi wygląda na to, że wystarczyłoby odblokować endpointy w namespace ‚contact-form-7’. Nie mam teraz jak tego sprawdzić, więc to tylko przypuszczenia.

          • Paweł Knapek

            Właśnie też nie miałem okazji tego osobiście sprawdzić, dlatego napisałem „wydaje się”. – może w wolnej chwili zrobię test. Ale w paru miejscach ludziska wspominały o problemach przy włączonej autoryzacji, więc coś może być na rzeczy.

          • luk

            Witajcie,
            Też się „nadziałem” teraz na problem z CF7 i REST’em.
            Rozwiązanie jakie widzę to całkowita blokada REST’a ale stricte w htaccess (jeden ze sposobów z prezentacji wp magus).
            Wówczas CF7 przepuszcza (przynajmniej po szybkim teście tak to widzę).
            Co sądzicie o takim rozwiązaniu?

          • Paweł Knapek

            Masz na myśli pewnie wycinanie regułką ruchu na /wp-json/wp/ – tak, zadziała, bo CF7 leci na /wp-json/contact-form-7/ . Metoda z blokowaniem endpointów tez zadziała.