Как защитить WordPress от атак на REST API: 6 проверенных методов

turned-on monitor

Краткое содержание

Введение. Почему REST API – самая уязвимая точка WordPress

С версии 4.7 WordPress открыл публичный REST API, который позволяет получать и изменять данные через HTTP‑запросы. Это удобно для мобильных приложений и внешних сервисов, но одновременно создаёт широкую поверхность атаки: переборы, CSRF, XSS и даже удалённое выполнение кода. По данным WPBox, более 30 % уязвимостей в плагинах связаны именно с недостаточной проверкой запросов к API.

В этой статье мы разберём семь практических мер, которые позволяют полностью обезопасить REST API без потери функциональности. Все рекомендации протестированы на WordPress 5.9+ и совместимы с PHP 8.

1. Проверка nonce в запросах к API

Nonce (number used once) – одноразовый токен, генерируемый WordPress и проверяемый на сервере. Он защищает от CSRF‑атак, когда злоумышленник пытается выполнить запрос от имени авторизованного пользователя.

Как добавить nonce в JavaScript‑клиент

function enqueue_my_scripts() { wp_enqueue_script( 'my-app', get_template_directory_uri(). '/js/app.js', array( 'wp-api' ), null, true ); wp_localize_script( 'my-app', 'myApp', array( 'nonce' => wp_create_nonce( 'wp_rest' ), 'restUrl' => esc_url_raw( rest_url() ), ) ); } add_action( 'wp_enqueue_scripts', 'enqueue_my_scripts' ); 

В JavaScript запрос будет выглядеть так:

fetch( myApp.restUrl + 'wp/v2/posts', { method: 'POST', headers: { 'X-WP-Nonce': myApp.nonce, 'Content-Type': 'application/json' }, body: JSON.stringify({ title: 'Новый пост' }) });

На сервере WordPress автоматически проверит заголовок X-WP-Nonce. Если токен недействителен – запрос будет отклонён с кодом 403.

2. Ограничение доступа к API по IP‑адресу

Для администраторов и критически важных эндпоинтов часто достаточно разрешить запросы только с белого списка IP. Это простая, но эффективная мера против массовых сканеров.

Пример реализации через фильтр rest_authentication_errors

function restrict_rest_api_by_ip( $result ) { // Список доверенных IP (можно хранить в опциях) $whitelist = array( '203.0.113.10', '198.51.100.25' ); $client_ip = $_SERVER['REMOTE_ADDR']; // Применяем только к роутам, требующим админские права if ( current_user_can( 'manage_options' ) &&! in_array( $client_ip, $whitelist ) ) { return new WP_Error( 'rest_forbidden_ip', 'Ваш IP не имеет доступа к REST API', array( 'status' => 403 ) ); } return $result; } add_filter( 'rest_authentication_errors', 'restrict_rest_api_by_ip' ); 

Не забывайте добавить собственный IP, иначе вы сами потеряете доступ к админ‑панели через API.

3. Отключение ненужных роутов и эндпоинтов

WordPress по умолчанию регистрирует более 30 роутов, многие из которых не используются на сайте. Каждый открытый роут – потенциальный вектор атаки.

Убираем публичный доступ к пользовательским данным

function disable_unused_rest_routes() { // Отключаем список всех пользователей remove_action( 'rest_api_init', 'wp_oembed_register_route' ); // пример удаления oEmbed add_filter( 'rest_endpoints', function( $endpoints ) { if ( isset( $endpoints['/wp/v2/users'] ) ) { unset( $endpoints['/wp/v2/users'] ); } if ( isset( $endpoints['/wp/v2/users/(?Pd+)'] ) ) { unset( $endpoints['/wp/v2/users/(?Pd+)'] ); } return $endpoints; } ); } add_action( 'rest_api_init', 'disable_unused_rest_routes', 999 ); 

Для полного аудита используйте Cypress WordPress Тестирование – скрипт покажет, какие эндпоинты отвечают и какие данные возвращаются.

4. Кастомные разрешения и политики доступа

WordPress позволяет задавать собственные возможности (capabilities) для REST‑запросов. Это удобно, когда нужно открыть доступ только определённым ролям.

Создаём кастомный permission_callback

function register_private_route() { register_rest_route( 'myplugin/v1', '/secure-data', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'myplugin_get_secure_data', 'permission_callback' => function( $request ) { // Доступ только у редакторов и выше return current_user_can( 'edit_others_posts' ); }, ) ); } add_action( 'rest_api_init', 'register_private_route' ); function myplugin_get_secure_data( $request ) { return rest_ensure_response( array( 'secret' => 'Это конфиденциальные данные' ) ); } 

Если пользователь не имеет нужных прав, WordPress вернёт 401 Unauthorized без раскрытия деталей.

5. Защита уровня сервера: WAF и OWASP Core Rule Set

Ни одна внутренняя мера не заменит надёжный веб‑аппликационный фаервол (WAF). При правильной настройке он блокирует попытки эксплуатации уязвимостей в API.

Подробную инструкцию по интеграции OWASP CRS в WordPress‑сайт вы найдёте в статье Защита WordPress с OWASP Core Rule Set в WAF. Обязательно включите правило 942100 – оно отслеживает запросы к */wp-json/* без корректных заголовков.

6. Мониторинг и логирование запросов к API

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

Пример логгера, записывающего в wp-content/debug.log

function log_rest_requests( $request ) { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { $log_entry = sprintf( "[REST] %s %s %sn", $_SERVER['REMOTE_ADDR'], $request->get_method(), $request->get_route() ); error_log( $log_entry, 3, WP_CONTENT_DIR. '/debug.log' ); } return $request; } add_filter( 'rest_pre_dispatch', 'log_rest_requests' ); 

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

Заключение. Комплексный подход к защите REST API

Защита REST API WordPress – это не один трюк, а набор взаимодополняющих техник: проверка nonce, IP‑фильтрация, отключение неиспользуемых роутов, кастомные права, WAF и постоянный мониторинг. Применив все семь шагов, вы снизите риск компрометации сайта до минимумa и сможете спокойно использовать API для мобильных приложений, Headless‑решений и интеграций.

Не откладывайте – настройте защиту уже сегодня и проверьте её с помощью инструментов ускорения TTFB. Ваши пользователи и данные заслуживают надёжной обороны.

❓ Часто задаваемые вопросы

Как проверить, что nonce действительно проверяется сервером?

Отправьте запрос к API без заголовка X-WP-Nonce или с неверным токеном – сервер вернёт ошибку 403 и сообщение «rest_cookie_invalid_nonce».

Можно ли полностью отключить REST API для публичных пользователей?

Да, добавив фильтр rest_authentication_errors, который возвращает WP_Error для неавторизованных запросов, вы полностью закроете API.

Влияет ли ограничение по IP на работу мобильных приложений?

Если мобильное приложение использует фиксированный набор серверов, добавить их IP в белый список – иначе запросы будут блокированы.

Нужен ли WAF, если я уже использую все перечисленные меры?

WAF обеспечивает дополнительный уровень защиты от новых эксплойтов и сканеров, поэтому рекомендуется использовать его совместно с внутренними мерами.