Перейти к содержимому

REST API WordPress публично перечисляет используемые плагины

Предупреждение Весь домен Безопасность

Общие инструкции. Откройте эту статью из отчёта PageCheck, чтобы увидеть её с плагинами, которые называет индекс вашего сайта, и с тем, какие из них используют браузеры ваших посетителей.

Что это такое

REST API WordPress позволяет скриптам читать и изменять сайт через адреса под /wp-json/: им пользуются редактор блоков, приложения и многие плагины. Его индекс перечисляет каждое «пространство имён», которое регистрирует сайт, — группу адресов, — и самому WordPress принадлежит лишь несколько из них. Каждое другое пространство имён принадлежит какому-то плагину.

Что не так

Индекс отвечает любому, кто его запросит, а его пространства имён называют плагины сайта. С этим списком злоумышленнику не нужно гадать: далее версия каждого плагина читается из его собственных файлов и сверяется с публичными списками известных уязвимостей. Сама страница выдаёт только плагины, которые загружают в неё файлы; индекс называет и те, которые этого не делают, — плагины SEO, форм, резервного копирования, безопасности и администрирования.

Как исправить

API остаётся; только его карта и части, которые посетители никогда не вызывают, скрываются от всех, кто не вошёл в систему как сотрудник. Скрытые адреса должны отвечать «не найдено» (404), а не «не авторизован» (401): 401 всё равно подтверждает, что плагин есть.

1. Выясните, какие пространства имён вызывают ваши страницы. Откройте сайт в приватном окне браузера, откройте инструменты разработчика (F12) → Network, задайте фильтр wp-json и пользуйтесь сайтом как посетитель: отправьте форму, добавьте что-нибудь в корзину, откройте оформление заказа, выполните поиск. Каждый запрос в списке называет пространство имён, которое нужно оставить.

Самые распространённые:

  • Contact Form 7 отправляет свои формы через REST API.
  • Блочные корзина, оформление заказа и мини-корзина WooCommerce читают Store API (wc/store).
  • Счётчики просмотров, такие как WP Statistics и WordPress Popular Posts, записывают через него посещения.
  • Плагины сообществ, пожертвований и согласия на cookie (BuddyPress, GiveWP, Complianz) используют его на страницах.

2. Скройте остальное от посетителей. Сохраните это как wp-content/mu-plugins/hide-rest-map.php (папку, возможно, придётся создать; файлы в ней всегда активны). Впишите в список пространства имён из шага 1 — каждое сохраняется вместе со всем, что под ним.

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 );

Все, кто может редактировать содержимое, сохраняют весь API, поэтому редактор блоков, экраны администрирования WooCommerce и других плагинов и «Здоровье сайта» работают как прежде. Плагины безопасности предлагают то же самое в виде настройки («Отключить REST API для посетителей» или похожей); убедитесь, что она принимает список исключений и отвечает 404, а не 401.

Не рекомендуется: распространённый фрагмент кода, который закрывает посетителям весь API через rest_authentication_errors. Он ломает формы и блочную корзину и всё равно отвечает 401 на каждый адрес, что подтверждает существование каждого плагина.

3. Проверьте. Откройте https://example.com/wp-json/ в приватном окне: ответ должен быть «не найдено» (404, rest_no_route). Затем отправьте форму и воспользуйтесь корзиной или тем, что ещё делают ваши страницы, и запустите эту проверку снова.

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.

Проверьте свой сайт, чтобы узнать, есть ли у него эта проблема. Проверить сайт