REST API в WordPress часто оставляют открытым «по умолчанию», а потом удивляются лишним запросам, утечке служебных данных и шуму в логах. Полностью выключать API обычно не нужно: редактор блоков, некоторые плагины и интеграции завязаны на него. На практике задача почти всегда звучит иначе — ограничить публичный доступ к REST API, не ломая авторизацию, админку и рабочие интеграции.
Ниже разберём, как понять, что именно у вас открыто, какие варианты ограничения реально работают в WordPress, и как проверить, что после правки сайт не потерял нужные функции.
Когда REST API становится проблемой
Сам по себе REST API не является уязвимостью. Проблема начинается, когда сайт отдаёт слишком много информации анонимным посетителям или когда сторонний код бездумно опрашивает публичные endpoints. Типичные симптомы:
- в ответах
/wp-json/видны заголовки, названия типов записей, таксономии и другие служебные данные; - в логах много запросов к
/wp-json/wp/v2/posts,/wp-json/wp/v2/usersи похожим адресам; - сканеры безопасности показывают лишнюю поверхность атаки;
- на сайте есть плагины, которым нужен REST, но анонимным пользователям он не нужен.
Важно не путать два сценария: закрыть API для всех и ограничить только публичные запросы. Второй вариант обычно безопаснее и практичнее.
Диагностика: что именно открыто сейчас
Перед изменениями проверьте, как отвечает сайт без авторизации. Это можно сделать в браузере или через curl.
curl -I https://example.com/wp-json/Если сервер отдаёт 200 OK, публичная точка входа доступна. Это ещё не ошибка, но повод посмотреть, какие данные доступны без логина.
Проверьте несколько типовых endpoint'ов:
curl https://example.com/wp-json/wp/v2/posts?per_page=1
curl https://example.com/wp-json/wp/v2/users?per_page=1Если ответы приходят без авторизации, значит API открыт как минимум для чтения. Для части сайтов это нормально, но если вы не используете headless-фронтенд, внешние интеграции или публичный каталог через API, такой доступ часто избыточен.
Что нельзя ломать
Перед ограничением API проверьте, не завязаны ли на него:
- редактор блоков Gutenberg;
- поиск и фильтры в админке некоторых плагинов;
- формы, которые отправляют данные через REST;
- мобильные приложения и внешние сервисы;
- кастомные темы с AJAX/REST-запросами.
Как ограничить REST API без полного отключения
Самый безопасный путь — разрешить REST API только авторизованным пользователям, а для анонимных запросов вернуть ошибку. Это не универсальное решение, но для многих корпоративных и контентных сайтов оно подходит.
Добавьте код в functions.php дочерней темы или в собственный мини-плагин:
add_filter( 'rest_authentication_errors', function( $result ) {
if ( true === $result || is_wp_error( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
return new WP_Error(
'rest_forbidden',
__( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
array( 'status' => 403 )
);
} );Что делает этот код:
- не вмешивается в уже существующие ошибки аутентификации;
- не мешает авторизованным пользователям;
- блокирует анонимные REST-запросы с кодом
403.
Это грубое ограничение. Если у вас есть публичный фронтенд, который читает данные через REST, такой вариант его сломает. Тогда лучше идти точечно — закрывать только отдельные endpoints.
Точечная блокировка отдельных REST endpoints
Если нужно закрыть только пользователей или служебные типы записей, удобнее фильтровать маршруты по namespace и endpoint. Например, можно запретить анонимный доступ к списку пользователей, но оставить остальное открытым.
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( isset( $endpoints['/wp/v2/users'] ) ) {
foreach ( $endpoints['/wp/v2/users'] as $index => $handler ) {
$endpoints['/wp/v2/users'][ $index ]['permission_callback'] = function () {
return current_user_can( 'list_users' );
};
}
}
return $endpoints;
} );Такой подход полезен, когда вам не нужен полный запрет API, но нужно убрать самые чувствительные точки. Аналогично можно обработать собственные маршруты плагинов, если они зарегистрированы через register_rest_route().
Когда лучше не писать код вручную
Если задача не в тонкой настройке, а в общей чистке сайта от лишних публичных точек, проще использовать плагин с понятными настройками. Например, в Clearfy Pro есть набор опций для технической оптимизации и отключения части лишнего функционала без ручного редактирования кода. Это не отменяет проверки совместимости, но снижает риск ошибки в теме.
| Подход | Плюсы | Минусы |
|---|---|---|
| Плагин | Быстро, без правки темы, проще откатить | Меньше гибкости, зависит от интерфейса плагина |
| Код в теме/мини-плагине | Точный контроль, можно закрыть только нужные endpoints | Нужно тестировать совместимость и обновления |
| Полное отключение REST | Максимально жёсткое ограничение | Часто ломает редактор и плагины, редко оправдано |
Пошаговое внедрение без поломок
- Сделайте резервную копию файлов и базы.
- Проверьте, какие страницы, плагины и интеграции используют REST API.
- Выберите уровень ограничения: весь публичный API или только отдельные маршруты.
- Добавьте код в дочернюю тему или мини-плагин, а не в основной файл темы.
- Очистите кеш страницы и серверный кеш, если он есть.
- Проверьте фронтенд, админку и формы отправки данных.
Как проверить, что решение сработало
После внедрения повторите те же запросы, что использовали в диагностике. Для варианта с полным ограничением анонимных запросов ответ должен стать 403 Forbidden.
curl -I https://example.com/wp-json/
curl https://example.com/wp-json/wp/v2/posts?per_page=1Дополнительно проверьте:
- открывается ли редактор записей в админке;
- работают ли формы, если они отправляют данные через REST;
- нет ли ошибок JavaScript в консоли браузера;
- не появились ли 403 в логах у нужных интеграций.
Если сайт использует публичный фронтенд на REST, проверяйте не только главную страницу, но и страницы, где данные подгружаются динамически: фильтры, поиск, карточки записей, блоки с комментариями.
Частые ошибки и как их исправить
Сломали Gutenberg
Причина обычно одна: вы заблокировали REST API для всех, включая авторизованных пользователей, или фильтр срабатывает слишком рано. Исправление — разрешить доступ для залогиненных и не трогать запросы из админки.
Закрыли API, но данные всё равно доступны
Так бывает, если часть информации отдаёт не REST, а обычные шаблоны, AJAX-обработчики или кэш. Проверьте реальные URL, а не только /wp-json/.
Появились ошибки у плагина
Некоторые плагины используют собственные REST-маршруты. Если вы закрыли всё подряд, добавьте исключения для нужного namespace или отключите ограничение точечно.
Сделали правку в основной теме
После обновления тема перезапишется, и ограничение исчезнет. Для таких правок используйте дочернюю тему или отдельный мини-плагин.
Практика безопасности и производительности
Ограничение REST API не заменяет базовую защиту сайта. Если у вас уже есть лишние публичные точки входа, имеет смысл параллельно проверить:
- не светятся ли в открытом доступе тестовые страницы и черновики;
- не отдаёт ли сервер лишние заголовки и версии;
- не висит ли тяжёлый кеш на страницах, где API нужен только авторизованным;
- не создаёт ли плагин собственные публичные маршруты без необходимости.
Если задача шире, чем один REST endpoint, удобнее собрать техническую чистку в одном месте: отключение лишних функций, удаление дублей, базовая SEO-гигиена и контроль служебных запросов. В таком случае лучше не разносить правки по десятку файлов темы, а держать их в одном управляемом слое.
Главная мысль простая: не выключайте REST API «на всякий случай». Сначала посмотрите, кто его реально использует, затем закройте только то, что не должно быть публичным. Так вы уменьшите поверхность атаки и не сломаете рабочие сценарии сайта.