REST API WordPressa publicznie wymienia wtyczki, z których korzysta
Ogólne instrukcje. Otwórz ten artykuł z raportu PageCheck, aby zobaczyć go wypełnionego wtyczkami, które wymienia indeks Twojej witryny, oraz informacją, z których z nich korzystają przeglądarki odwiedzających.
Co to jest
REST API WordPressa pozwala skryptom odczytywać i zmieniać witrynę przez adresy pod /wp-json/: korzystają z niego edytor blokowy, aplikacje i wiele wtyczek. Jego indeks wymienia każdą „przestrzeń nazw”, którą witryna rejestruje — grupę adresów — a do samego WordPressa należy tylko kilka z nich. Każda inna przestrzeń nazw należy do wtyczki.
Co jest nie tak
Indeks odpowiada każdemu, kto o niego poprosi, a jego przestrzenie nazw wskazują wtyczki witryny. Mając tę listę, atakujący nie zgaduje: wersję każdej wtyczki odczytuje następnie z jej własnych plików i porównuje z publicznymi listami znanych luk bezpieczeństwa. Sama strona zdradza tylko wtyczki, które wczytują do niej pliki; indeks wymienia także te, które tego nie robią — wtyczki SEO, formularzy, kopii zapasowych, bezpieczeństwa i administracyjne.
Jak naprawić
API zostaje; przed osobami niezalogowanymi jako personel ukrywa się tylko jego mapę i części, których odwiedzający nigdy nie wywołują. Ukryte adresy powinny odpowiadać „nie znaleziono” (404), a nie „brak autoryzacji” (401): 401 nadal potwierdza, że wtyczka tam jest.
1. Ustal, które przestrzenie nazw wywołują Twoje strony. Otwórz witrynę w oknie prywatnym przeglądarki, otwórz narzędzia deweloperskie (F12) → Sieć / Network, ustaw filtr wp-json i korzystaj z witryny jak odwiedzający: wyślij formularz, dodaj coś do koszyka, otwórz stronę zamówienia, wyszukaj. Każde wymienione żądanie wskazuje przestrzeń nazw do zachowania.
Najczęstsze:
- Contact Form 7 wysyła swoje formularze przez REST API.
- Blokowy koszyk, strona zamówienia i mini-koszyk WooCommerce odczytują Store API (wc/store).
- Liczniki odsłon, takie jak WP Statistics i WordPress Popular Posts, rejestrują przez nie wizyty.
- Wtyczki społecznościowe, do darowizn i zgód (BuddyPress, GiveWP, Complianz) korzystają z niego na stronach.
2. Ukryj resztę przed odwiedzającymi.
Zapisz to jako wp-content/mu-plugins/hide-rest-map.php (folder może trzeba utworzyć; pliki w nim są zawsze aktywne). Wpisz na listę przestrzenie nazw z kroku 1 — każda zostaje zachowana wraz ze wszystkim, co pod nią.
wp-content/mu-plugins/hide-rest-map.php
<?php
/* Hide the REST API's map from visitors who are not logged in. */
add_filter( 'rest_endpoints', function ( $endpoints ) {
if ( current_user_can( 'edit_posts' ) ) {
return $endpoints; // staff keep everything
}
// Namespaces your pages call. Everything else answers 404 to visitors.
$keep = array( 'wc/store', 'contact-form-7/v1' );
foreach ( array_keys( $endpoints ) as $route ) {
$kept = false;
foreach ( $keep as $namespace ) {
if ( 0 === strpos( $route, '/' . $namespace . '/' ) ) {
$kept = true;
break;
}
}
if ( ! $kept ) {
unset( $endpoints[ $route ] );
}
}
return $endpoints;
}, 5 );
// No pointer to the API in the pages' head and headers.
remove_action( 'wp_head', 'rest_output_link_wp_head' );
remove_action( 'template_redirect', 'rest_output_link_header', 11 );
Każdy, kto może edytować treści, zachowuje całe API, więc edytor blokowy, ekrany administracyjne WooCommerce i innych wtyczek oraz Zdrowie witryny działają jak dotąd. Wtyczki bezpieczeństwa oferują to samo jako ustawienie („Wyłącz REST API dla odwiedzających” lub podobne); upewnij się, że przyjmuje listę wyjątków i odpowiada 404, a nie 401.
Niezalecane: popularny fragment kodu, który odmawia odwiedzającym całego API przez rest_authentication_errors. Psuje formularze i blokowy koszyk, a dla każdego adresu nadal odpowiada 401, co potwierdza, że dana wtyczka istnieje.
3. Sprawdź.
Otwórz https://example.com/wp-json/ w oknie prywatnym: powinien odpowiedzieć „nie znaleziono” (404, rest_no_route). Następnie wyślij formularz i skorzystaj z koszyka lub czegokolwiek innego, co robią Twoje strony, i uruchom tę kontrolę ponownie.
Hide my WordPress site's REST API map from visitors who are not logged in, without breaking the features that use the API. https://example.com/wp-json/ currently answers anyone and lists every namespace, i.e. every plugin. Do this: 1. Find which namespaces the public pages call (forms, cart, checkout, view counters): grep the theme and plugins for wp-json / rest_url / apiFetch, and check the browser's network tab as a visitor. 2. Add a must-use plugin (wp-content/mu-plugins/hide-rest-map.php) with a rest_endpoints filter: when the user cannot edit_posts, unset every route except those under the kept namespaces (match '/<namespace>/' as a prefix of the route), so the index '/', every namespace index and the other routes answer 404 rest_no_route, never 401. Also remove_action wp_head rest_output_link_wp_head and template_redirect rest_output_link_header (priority 11). 3. Do not use rest_authentication_errors to refuse the whole API: it breaks visitor-facing features and answers 401, which confirms the plugins. 4. Verify: /wp-json/ and /wp-json/wp/v2 answer 404 for a visitor and still work for an editor; the kept features work in a private window; no <link rel="https://api.w.org/"> and no Link header on the pages. Tell me exactly which file you added and which namespaces you kept.
Temat: example.com – prośba o ukrycie mapy REST API WordPressa przed odwiedzającymi Dzień dobry, Test witryny (PageCheck) wykazał, że https://example.com/wp-json/ odpowiada każdemu i wymienia wszystkie wtyczki naszej witryny, co daje atakującym gotową listę do sprawdzenia po kolei. Prosimy o: 1. Ukryć indeks REST API (/wp-json/) i każdą przestrzeń nazw, której nasze strony nie wywołują, przed niezalogowanymi odwiedzającymi, tak aby odpowiadały 404 (mała wtyczka must-use z filtrem rest_endpoints albo ustawienie wtyczki bezpieczeństwa z wyjątkami). 2. Zachować przestrzenie nazw, z których korzystają nasze formularze, sklep lub inne funkcje dla odwiedzających. 3. Usunąć odnośnik do REST API z sekcji head stron i z nagłówków HTTP. 4. Sprawdzić, czy formularze, koszyk i ekrany administracyjne nadal działają. Dziękuję!
Sprawdź swoją stronę, aby zobaczyć, czy ma ten problem. Sprawdź stronę