Когда сайт начинает получать странные запросы к /xmlrpc.php, а в логах видны обращения к REST API от ботов и сканеров, проблема обычно не в одной «дыре», а в наборе открытых точек доступа. Полностью закрывать всё подряд нельзя: редактор, мобильные приложения, внешние сервисы и часть плагинов используют REST API. Поэтому задача не в тотальной блокировке, а в том, чтобы оставить рабочие сценарии и убрать лишнее.
Что именно стоит проверить в первую очередь
Перед правками посмотрите, какие точки доступа реально используются. На практике чаще всего нужно разделить три вещи: XML-RPC, публичные REST-эндпоинты и доступ к админке по слабым правилам. Если сайт не использует Jetpack, мобильное приложение WordPress и удалённую публикацию через XML-RPC, этот канал можно отключать без сожалений. REST API трогать аккуратнее: его используют Gutenberg, многие формы, кэши, интеграции и плагины авторизации.
Диагностика проблемы
- В логах веб-сервера много запросов к
/xmlrpc.phpс одинаковыми IP или user-agent. - В
/wp-json/видны частые обращения к публичным маршрутам, хотя внешние интеграции не нужны. - На сайте есть формы входа, но нет ограничений по частоте попыток и нет защиты от перебора паролей.
- Плагины кэширования или безопасности уже меняли поведение REST API, и после этого появились ошибки в редакторе.
Если есть сомнения, сначала проверьте, не ломается ли редактор блоков и не завязаны ли на REST API сторонние сервисы. Это проще сделать на staging-копии, чем потом ловить проблемы на боевом сайте.
Пошаговое решение без лишнего риска
Самый безопасный путь — не удалять ядро и не править файлы WordPress вручную, а закрывать доступ на уровне правил и фильтров. Для XML-RPC достаточно либо отключить сам файл, либо отдать на него 403. Для REST API лучше ограничивать не всё подряд, а только публичные маршруты, которые не нужны гостям.
1. Отключить XML-RPC через фильтр
Если вам не нужны pingback, удалённая публикация и старые интеграции, добавьте фильтр в мини-плагин или functions.php дочерней темы. Для боевого сайта мини-плагин надёжнее: он не зависит от темы.
<?php
/**
* Plugin Name: WP Sync Security Tweaks
*/
add_filter( 'xmlrpc_enabled', '__return_false' );
После этого WordPress перестанет принимать XML-RPC-запросы на уровне ядра. Если у вас есть серверный доступ, дополнительно можно закрыть файл на уровне веб-сервера.
2. Заблокировать XML-RPC на уровне Nginx или Apache
Это полезно, если боты продолжают стучаться в xmlrpc.php и вы хотите отсечь их раньше PHP.
# Nginx
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
# Apache
<Files "xmlrpc.php">
Require all denied
</Files>
Такой вариант не зависит от плагинов и работает даже если WordPress временно недоступен. Но его нужно вносить аккуратно, особенно если сайт обслуживается через общий конфиг хостинга.
3. Ограничить REST API для неавторизованных пользователей
Полностью отключать REST API обычно плохая идея. Вместо этого можно закрыть часть маршрутов для гостей, если они не нужны. Например, на сайте без публичного каталога авторов и без внешних интеграций можно ограничить доступ к пользовательским данным.
<?php
add_filter( 'rest_authentication_errors', function ( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( ! is_user_logged_in() ) {
$uri = $_SERVER['REQUEST_URI'] ?? '';
if ( strpos( $uri, '/wp-json/wp/v2/users' ) !== false ) {
return new WP_Error(
'rest_forbidden',
'REST API users endpoint is disabled for guests.',
array( 'status' => 403 )
);
}
}
return $result;
} );
Этот пример не ломает весь REST API, а режет только один конкретный маршрут. Если у вас есть другие публичные эндпоинты, их нужно перечислять отдельно.
4. Добавить ограничение по частоте для формы входа
Даже если XML-RPC закрыт, перебор паролей часто идёт через /wp-login.php. Здесь помогает rate limit на уровне сервера, WAF или плагина безопасности. Если нужен кодовый вариант, можно хотя бы временно блокировать подозрительные попытки по IP через серверные правила. В PHP это делать неудобно и ненадёжно, поэтому лучше не тащить такую логику в WordPress.
Как понять, что всё сработало
Проверка должна быть не только визуальной. Смотрите на конкретные ответы сервера и поведение редактора.
- Откройте
/xmlrpc.php: должен быть запрет доступа или пустой ответ, а не рабочая XML-RPC-форма. - Проверьте
https://example.com/wp-json/: базовый индекс REST API должен открываться, если вы его не отключали полностью. - Попробуйте открыть закрытый маршрут, например
/wp-json/wp/v2/usersдля гостя: должен возвращаться403. - Создайте или отредактируйте запись в Gutenberg: если блоки, медиа и автосохранение работают, вы не сломали нужный REST-трафик.
- Посмотрите логи сервера через 1–2 дня: количество обращений к
xmlrpc.phpдолжно снизиться до отказов на уровне веб-сервера.
Если после изменений редактор начал выдавать ошибки загрузки, первым делом откатите ограничения на REST API, а не на XML-RPC. Обычно проблема именно в слишком широком фильтре.
Сравнение подходов: плагин, код или сервер
| Подход | Что закрывает | Плюсы | Минусы |
|---|---|---|---|
| Плагин безопасности | XML-RPC, логины, часть REST | Быстро, без правок сервера | Зависимость от стороннего кода, лишняя нагрузка |
| Код в мини-плагине | Точечные REST-ограничения, XML-RPC | Контроль над логикой, легко версионировать | Нужно понимать, что именно блокируется |
| Nginx/Apache | XML-RPC и часть атак до PHP | Самый дешёвый по ресурсам вариант | Требует доступа к конфигу и аккуратности |
Если у вас обычный сайт без сложных интеграций, чаще всего хватает связки: серверная блокировка XML-RPC плюс точечные ограничения REST API кодом. Плагин имеет смысл, когда нужен интерфейс для команды без доступа к конфигам.
Частые ошибки и как их исправить
Сломали Gutenberg после отключения REST API
Причина почти всегда одна: фильтр блокирует не один маршрут, а весь REST API. Уберите глобальные запреты и оставьте только конкретные эндпоинты, которые действительно не нужны.
Закрыли XML-RPC, но атаки продолжаются
Это нормально, если бот продолжает стучаться в файл по старым спискам. Проверьте блокировку на уровне веб-сервера и убедитесь, что ответ действительно 403, а не просто обработка WordPress с ошибкой.
Появились проблемы с мобильным приложением или внешним сервисом
Значит, у вас был живой сценарий через XML-RPC или REST API. Не пытайтесь «дожать» блокировку вслепую: сначала найдите конкретный сервис, затем либо переведите его на REST с авторизацией по приложению, либо оставьте нужный маршрут открытым.
Сделали правки в теме, а после обновления всё пропало
Код в functions.php темы — плохое место для таких настроек. Перенесите его в мини-плагин или mu-plugin, чтобы он не зависел от смены темы.
Практические советы по безопасности и производительности
Если сайт уже под атакой, не ограничивайтесь только XML-RPC. Проверьте:
- есть ли ограничение попыток входа;
- закрыт ли доступ к
wp-adminпо IP или через дополнительную авторизацию, если это корпоративный сайт; - не светятся ли лишние публичные маршруты REST API;
- не включён ли pingback, если он не нужен;
- не пишет ли сервер слишком много ошибок в лог из-за постоянных сканирований.
Если нужен более широкий набор технических правок для SEO, дублей и чистки сайта, такие задачи удобно решать через отдельный набор оптимизаций, а не смешивать всё в один тяжёлый security-плагин. Но для закрытия точек доступа лучше держать логику минимальной и прозрачной.
Итоговая схема простая: XML-RPC закрываем жёстко, REST API ограничиваем точечно, а рабочие сценарии проверяем на staging и в логах. Тогда сайт остаётся доступным для редакторов и интеграций, но перестаёт быть удобной мишенью для автоматических сканеров.