Если в ответе по адресу /wp-json/ вы видите лишние данные, это не всегда уязвимость, но почти всегда повод проверить, что именно отдает REST API и кому. Полностью закрывать wp-json на живом сайте можно не в каждом случае: часть тем, редакторов, мобильных приложений и плагинов использует REST API для работы фронтенда. Поэтому правильная задача обычно звучит так: ограничить доступ точечно, а не ломать API целиком.
Самый безопасный подход зависит от того, что именно вы хотите скрыть. Иногда достаточно убрать лишние эндпоинты и данные из ответа. Иногда нужно запретить доступ к API для неавторизованных пользователей. А иногда — закрыть только отдельные маршруты, оставив остальной сайт и нужные интеграции рабочими.
Сначала определите, что именно нужно ограничить
Перед изменениями посмотрите, как сейчас ведёт себя REST API. Откройте https://ваш-домен.ru/wp-json/ в браузере и проверьте:
- открывается ли общий индекс API без авторизации;
- есть ли в ответе маршруты плагинов и темы, которые вам не нужны;
- возвращаются ли данные пользователей, записей, таксономий или медиа;
- ломается ли после ограничений фронтенд, форма входа, поиск, редактор блоков или сторонний сервис.
Если задача только в том, чтобы скрыть часть информации, не трогайте весь REST API. Если же вы хотите закрыть API от внешнего доступа полностью, сначала убедитесь, что сайт не использует его на публичной части. Для WordPress это особенно важно на сайтах с Gutenberg, headless-сценарием, AJAX-функциями и некоторыми конструкторами.
Ограничить доступ точечно через WordPress-фильтры
Если нужен контролируемый вариант без правок сервера, используйте фильтры WordPress. Это подходит, когда вы хотите запретить отдельные маршруты или скрыть API для неавторизованных пользователей, но оставить сайт рабочим.
Ниже пример, который блокирует доступ к REST API для гостей, но не мешает авторизованным пользователям. Добавлять его лучше в мини-плагин или в functions.php дочерней темы. Перед изменениями сделайте резервную копию: если на сайте есть публичные формы, редактор блоков или интеграции, такой запрет может их сломать.
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
return new WP_Error(
'rest_forbidden',
'REST API доступен только авторизованным пользователям.',
array( 'status' => 401 )
);
} );Этот вариант жёсткий: он закрывает весь REST API для неавторизованных посетителей. Для админки это обычно не проблема, но для публичного сайта — часто слишком грубо. Если вам нужно ограничить только часть маршрутов, лучше проверять конкретный путь.
Например, можно запретить только пользовательские маршруты, оставив стандартные эндпоинты WordPress доступными:
add_filter( 'rest_endpoints', function( $endpoints ) {
foreach ( $endpoints as $route => $handlers ) {
if ( strpos( $route, '/my-plugin/' ) === 0 ) {
unset( $endpoints[ $route ] );
}
}
return $endpoints;
} );Здесь важно понимать логику: вы не блокируете весь API, а убираете конкретный маршрут из списка. Такой способ полезен, если проблема в плагине или кастомной интеграции, которая публикует лишние данные.
Скрыть или ограничить отдельные данные в ответах REST API
Иногда доступ к wp-json как таковому не проблема. Проблема в том, что в ответах видны поля, которые не должны быть публичными: email, внутренние метаданные, служебные свойства записей, лишние пользовательские данные. В этом случае лучше не закрывать API целиком, а отфильтровать конкретные поля.
Для записей и страниц можно использовать фильтр rest_prepare_post и убрать ненужные данные из ответа. Пример ниже удаляет поле author из публичного ответа для гостей:
add_filter( 'rest_prepare_post', function( $response, $post, $request ) {
if ( is_user_logged_in() ) {
return $response;
}
$data = $response->get_data();
unset( $data['author'] );
$response->set_data( $data );
return $response;
}, 10, 3 );Если вам нужно скрывать данные пользователей, ориентируйтесь на конкретный маршрут и права доступа. WordPress уже ограничивает часть пользовательских данных, но кастомные поля, добавленные плагинами, могут попадать в ответ без дополнительной проверки. В таких случаях безопаснее дорабатывать сам endpoint, а не пытаться «запретить всё» на уровне сервера.
Закрыть wp-json на уровне сервера, если нужен жёсткий запрет
Этот вариант подходит, когда REST API на сайте не используется вообще или используется только в административной части, а публичный доступ вам не нужен. Но здесь есть риск: если сайт зависит от API, после блокировки могут перестать работать блоки, формы, виджеты или внешние интеграции. Перед правкой обязательно проверьте сайт на тестовой копии.
Для Apache можно добавить правило в .htaccess. Оно запретит доступ к /wp-json/ для всех запросов:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/wp-json/ [NC]
RewriteRule .* - [F,L]
</IfModule>Для Nginx правило обычно добавляют в конфигурацию сайта:
location ^~ /wp-json/ {
deny all;
return 403;
}После этого проверьте, что сервер действительно отдаёт 403 Forbidden на запрос к /wp-json/. Если у вас кэширующий плагин, CDN или прокси, очистите кэш и проверьте ответ напрямую, иначе можно увидеть старое поведение.
Когда лучше не закрывать wp-json полностью
Полная блокировка — не универсальное решение. На современных сайтах REST API часто нужен для нормальной работы интерфейса. Если вы закроете его без анализа, последствия обычно проявляются не сразу: редактор блоков начинает вести себя странно, формы перестают отправляться, а часть скриптов на фронтенде не получает данные.
Оставляйте API открытым, если:
- сайт использует Gutenberg и публичные блоки, завязанные на REST;
- есть headless-фронтенд или мобильное приложение;
- плагины на сайте явно используют REST API для AJAX-запросов;
- вам нужно только убрать лишние маршруты или поля, а не весь доступ.
В таких сценариях лучше ограничить доступ по ролям, скрыть отдельные маршруты или убрать чувствительные поля из ответа. Это даёт более предсказуемый результат и меньше шансов сломать сайт.
Как проверить, что ограничение работает и сайт не сломался
После настройки проверьте не только сам /wp-json/, но и реальные сценарии на сайте. Это занимает несколько минут и экономит время на поиске скрытых ошибок.
- Откройте
/wp-json/в браузере в режиме инкогнито и убедитесь, что доступ ограничен так, как вы задумали. - Проверьте вход в админку, редактор записей и сохранение контента.
- Протестируйте формы, поиск, комментарии и другие публичные функции, если они завязаны на JavaScript.
- Посмотрите логи сервера или консоль браузера на ошибки 401, 403 и 404.
Если после блокировки что-то перестало работать, не пытайтесь сразу «ослабить всё». Сначала найдите конкретный маршрут, который нужен сайту, и разрешите только его. В WordPress это почти всегда безопаснее, чем закрывать весь REST API целиком.
Если нужен именно точечный контроль без ручной правки кода на каждом сайте, для части задач помогает плагин оптимизации и чистки WordPress вроде Clearfy Pro: в таких инструментах часто есть настройки, связанные с отключением лишних возможностей WordPress и сокращением поверхности атаки. Но даже в этом случае перед применением стоит проверить, не используется ли REST API вашим сайтом или плагинами.