Как защитить WordPress от атак на REST API: 6 проверенных методов
Введение. Почему 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 обеспечивает дополнительный уровень защиты от новых эксплойтов и сканеров, поэтому рекомендуется использовать его совместно с внутренними мерами.