wpbackup.ru wordpress WPBackup.ru

Как запретить REST API для неавторизованных запросов в WordPress

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

Когда это нужно и как понять, что проблема именно в REST API

Сначала стоит проверить, есть ли у вас реальная причина для ограничения. На практике REST API трогают в трёх случаях: боты массово дергают публичные endpoints, в логах много запросов к /wp-json/wp/v2/, либо сайт начал отдавать лишнюю служебную информацию наружу. Если у вас есть редакторы Gutenberg, мобильное приложение WordPress, headless-фронтенд или интеграции с внешними сервисами, отключать всё подряд нельзя.

Диагностика проблемы

Посмотрите access log веб-сервера или логи аналитики и найдите частые обращения к REST API. Типичные признаки:

  • много запросов к /wp-json/ от одних и тех же IP;
  • в логах появляются 401 и 403 на REST endpoints;
  • редактор блоков в админке начинает ругаться на недоступный API;
  • кастомные формы, поиск или фронтенд на React/Vue перестают получать данные.

Проверка с консоли помогает быстро понять, что именно открыто:

curl -I https://example.com/wp-json/

Если ответ отдает 200, это нормально для публичного API. Вопрос не в самом факте доступности, а в том, какие маршруты вы хотите оставить открытыми.

Что лучше: плагин, код или серверное правило

Если задача — ограничить доступ без лишней магии, у вас есть три реалистичных варианта. Выбор зависит от того, нужен ли REST API для гостей вообще.

ПодходКогда подходитМинусы
Плагин безопасностиНужно быстро закрыть типовые сценарии без правки кодаМожет конфликтовать с другими плагинами и скрывать причину ошибки
Код в functions.php или MU-pluginНужен точечный контроль над доступомНужно аккуратно тестировать исключения
.htaccess / nginxНужно резать лишние запросы на уровне сервераСложнее не задеть легитимные маршруты

Для большинства сайтов самый безопасный вариант — ограничение через PHP с исключением для авторизованных пользователей и нужных маршрутов.

Пошаговое решение: ограничиваем REST API для гостей

Ниже вариант, который блокирует доступ к REST API для неавторизованных пользователей, но не ломает админку и не мешает авторизованным сессиям. Код лучше добавить в MU-plugin, чтобы он не зависел от темы.

Вариант через rest_authentication_errors

<?php
/**
 * Plugin Name: Restrict REST API for guests
 */

add_filter( 'rest_authentication_errors', function ( $result ) {
    if ( ! empty( $result ) ) {
        return $result;
    }

    if ( is_user_logged_in() ) {
        return $result;
    }

    // Разрешаем только базовую проверку доступности и публичные маршруты при необходимости.
    $uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';

    if ( strpos( $uri, '/wp-json/' ) === false ) {
        return $result;
    }

    return new WP_Error(
        'rest_forbidden',
        __( 'REST API доступен только авторизованным пользователям.', 'textdomain' ),
        array( 'status' => 401 )
    );
} );

Этот вариант грубый, но понятный. Он подходит, если сайт не использует публичные REST endpoints для гостей. Если у вас есть фронтенд-виджеты, поиск, формы или публичные данные, лучше сделать исключения.

Более аккуратно: блокируем только чувствительные маршруты

Если нужно оставить публичные данные, но закрыть служебные маршруты, фильтруйте конкретные namespace. Например, можно запретить доступ к wp/v2/users, чтобы не светить список пользователей.

<?php
add_filter( 'rest_endpoints', function ( $endpoints ) {
    if ( isset( $endpoints['/wp/v2/users'] ) ) {
        unset( $endpoints['/wp/v2/users'] );
    }

    if ( isset( $endpoints['/wp/v2/users/(?P<id>[\\d]+)'] ) ) {
        unset( $endpoints['/wp/v2/users/(?P<id>[\\d]+)'] );
    }

    return $endpoints;
} );

Это не отключает REST API целиком, а убирает конкретные маршруты. Такой подход полезен, если вы хотите уменьшить поверхность атаки и не сломать остальной функционал.

Проверка результата после внедрения

После правки проверьте не только ответ сервера, но и реальные сценарии в админке. Иначе можно получить «защиту», которая ломает редактор через скрытую ошибку.

  • Откройте /wp-json/ в браузере без авторизации и убедитесь, что поведение соответствует выбранной политике.
  • Зайдите в админку и проверьте редактор записей, загрузку блоков и сохранение черновика.
  • Если используется контактная форма или поиск с REST, протестируйте отправку и выдачу данных.
  • Проверьте логи сервера на новые 401 и 403 от легитимных клиентов.

Для быстрой проверки конкретного маршрута удобно использовать curl:

curl -i https://example.com/wp-json/wp/v2/posts
curl -i https://example.com/wp-json/wp/v2/users

Если первый запрос должен быть публичным, а второй — нет, вы увидите разницу сразу. Это хороший способ проверить, что ограничение работает точечно, а не «на глаз».

Частые ошибки и как их исправить

Сломали Gutenberg или редактор сайта

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

Отключили API, а интеграция с внешним сервисом перестала получать данные

Если у вас есть CRM, мобильное приложение или headless-фронтенд, им может быть нужен публичный endpoint или авторизация по application password / cookie. Перед ограничением составьте список реальных клиентов API и проверьте, какие маршруты они используют.

Поставили правило в теме и забыли после обновления

Код в functions.php легко потерять при смене темы. Для таких задач лучше использовать MU-plugin: файл в wp-content/mu-plugins/ не зависит от темы и загружается автоматически.

Скрыли проблему, но не убрали причину нагрузки

Если боты массово стучатся в REST API, одного запрета мало. Проверьте rate limiting на уровне nginx, WAF, Cloudflare или хотя бы базовую фильтрацию по IP и user-agent. Иначе нагрузка может просто сместиться на другие endpoints.

Практические советы по безопасности и производительности

Ограничение REST API — не замена нормальной гигиене сайта. Если цель именно безопасность, дополните настройку ещё несколькими мерами:

  • скройте список пользователей в публичных маршрутах;
  • не оставляйте тестовые endpoints и отладочные маршруты в продакшене;
  • проверьте, не отдают ли плагины лишние данные через собственные REST namespaces;
  • смотрите, не создаёт ли кеширование отдельные проблемы с авторизацией и nonce.

Если вам нужно быстро убрать лишние дубли, служебные элементы и мусорные страницы в целом по сайту, иногда удобнее сначала навести порядок в технической части, а уже потом ужесточать доступ к API. Для этого можно использовать Clearfy Pro, если он уже есть в вашем стеке: https://wpshop.ru/plugins/clearfy?utm_source=wpbackup.ru&utm_medium=article&utm_campaign=kak-zapretit-rest-api-dlya-neavtorizovannyh-zaprosov-v-wordpress.

Главное правило простое: сначала определите, какие маршруты реально нужны, потом закрывайте остальное. Тогда REST API перестанет быть лишней дырой в поверхности атаки и не превратится в источник случайных поломок.

×
Прокачай свой сайт WordPress!

WordPress

-20% на премиум темы и плагины

Создай сайт своей мечты ⋙