Если сайт на WordPress начал получать лишние запросы, а в логах видны обращения к /xmlrpc.php и публичным endpoint'ам REST API, это не всегда означает атаку, но почти всегда означает лишнюю поверхность входа. На небольших проектах это часто не нужно вообще. На рабочих сайтах задача обычно звучит так: убрать то, чем не пользуются, но не сломать редактор, авторизацию и внешние сервисы.
Ниже — рабочая схема: сначала проверяем, что именно используется, потом отключаем XML-RPC, ограничиваем публичные запросы к REST API и тестируем результат без гаданий.
Когда это действительно нужно
Отключать всё подряд не стоит. XML-RPC и REST API могут быть нужны для конкретных сценариев:
- мобильное приложение WordPress;
- Jetpack и похожие сервисы, которые завязаны на XML-RPC;
- интеграции с внешними системами через REST API;
- автоматизация публикаций и синхронизация контента;
- внешние формы, которые отправляют данные в
/wp-json/.
Если ничего из этого не используется, отключение лишних точек входа обычно оправдано. Если используется хотя бы один сценарий, лучше ограничивать доступ точечно, а не рубить всё целиком.
Диагностика: что именно у вас используется
Перед изменениями проверьте, есть ли реальные обращения к XML-RPC и REST API. Самый простой способ — посмотреть логи веб-сервера и список активных интеграций.
Что искать в логах
- частые запросы к
/xmlrpc.php; - обращения к
/wp-json/с внешних IP; - 401/403 на endpoint'ах REST API;
- ошибки авторизации у мобильных клиентов или сторонних сервисов.
Если у вас есть доступ к логам, полезно быстро отфильтровать запросы:
grep -E "xmlrpc\.php|wp-json" /var/log/nginx/access.log | tail -n 50На уровне WordPress проверьте, не завязаны ли на REST API темы, конструкторы, формы или кастомные интеграции. Если сайт использует Gutenberg и стандартную админку, REST API почти наверняка нужен хотя бы частично.
Пошаговое решение
1. Отключаем XML-RPC
Если XML-RPC не нужен, его можно заблокировать на уровне WordPress. Это безопаснее, чем полагаться только на плагин, который отключается вместе с темой или обновлением.
<?php
// В functions.php дочерней темы или в собственном мини-плагине.
add_filter( 'xmlrpc_enabled', '__return_false' );Если нужен более жесткий вариант, можно закрыть сам файл на уровне сервера. Для Nginx это обычно делают отдельным правилом:
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}Для Apache аналогичный эффект можно получить через .htaccess:
<Files xmlrpc.php>
Require all denied
</Files>Выбирайте один способ. Если блокируете на сервере, фильтр в WordPress уже не обязателен, но лишним не будет, если сайт переносится между окружениями.
2. Ограничиваем REST API для неавторизованных запросов
Полностью отключать REST API обычно плохая идея: редактор блоков, часть плагинов и внешние интеграции могут перестать работать. Практичнее ограничить доступ для гостей к тем endpoint'ам, которые вам не нужны.
Пример: разрешаем REST API только авторизованным пользователям, а для гостей возвращаем ошибку. Такой подход подходит для закрытых проектов, внутренних порталов и сайтов, где публичный API не используется.
<?php
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( is_user_logged_in() ) {
return $result;
}
return new WP_Error(
'rest_forbidden',
'REST API доступен только авторизованным пользователям.',
array( 'status' => 401 )
);
} );Если вам нужен REST API для публичной части, но вы хотите закрыть только отдельные маршруты, фильтр нужно делать точнее — по rest_endpoints или через проверку $_SERVER['REQUEST_URI'] на уровне сервера. Глобальная блокировка в таком случае слишком грубая.
3. Если нужен компромисс, ограничиваем только чувствительные маршруты
Иногда достаточно закрыть только те endpoint'ы, которые чаще всего используют для разведки. Например, можно ограничить доступ к пользовательским данным, если они не нужны на фронтенде.
Ниже пример, который блокирует запросы к маршрутам пользователей для гостей:
<?php
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( is_user_logged_in() ) {
return $endpoints;
}
foreach ( $endpoints as $route => $handlers ) {
if ( strpos( $route, '/wp/v2/users' ) === 0 ) {
unset( $endpoints[ $route ] );
}
}
return $endpoints;
} );Это не универсальное решение, но для многих сайтов оно лучше, чем полное отключение REST API. Перед внедрением проверьте, не использует ли тема или плагин данные пользователей на фронтенде.
Сравнение вариантов
| Подход | Что делает | Когда подходит | Компромисс |
|---|---|---|---|
| Плагин безопасности | Отключает или ограничивает XML-RPC и REST API через интерфейс | Если нужен быстрый запуск без кода | Зависимость от плагина и его настроек |
| Код в теме или мини-плагине | Даёт точный контроль над логикой | Если есть разработчик и нужен предсказуемый результат | Нужно тестировать после обновлений |
| Правило на сервере | Блокирует запросы до WordPress | Если нужно снизить нагрузку и отсечь мусор | Можно случайно задеть легитимные интеграции |
Проверка результата после внедрения
После изменений не ограничивайтесь тем, что страница открывается в браузере. Проверьте именно те точки входа, которые вы закрывали.
- Откройте
/xmlrpc.phpнапрямую — должен быть отказ в доступе или пустой ответ без полезной информации. - Проверьте
/wp-json/в режиме гостя — ожидаемое поведение зависит от выбранной схемы, но не должно быть лишнего доступа к закрытым данным. - Зайдите в админку и убедитесь, что редактор блоков работает.
- Если есть внешние интеграции, выполните тестовый запрос с их стороны.
- Посмотрите error log и access log на предмет новых 403/401 и PHP-ошибок.
Для быстрой ручной проверки можно использовать curl:
curl -I https://example.com/xmlrpc.php
curl -I https://example.com/wp-json/Если после блокировки REST API редактор начал сыпать ошибками, значит вы закрыли слишком много. Возвращайте доступ точечно, а не отключайте защиту целиком.
Частые ошибки и как их исправить
Отключили REST API полностью и сломали редактор
Такое бывает, если ставят жесткий фильтр без проверки сценариев. Gutenberg и некоторые плагины используют REST API для сохранения и загрузки данных. Решение: не блокировать всё подряд, а ограничивать только гостевые запросы или отдельные маршруты.
Закрыли XML-RPC, но забыли про плагин, который его использует
Если после блокировки перестали работать публикации из внешнего сервиса или синхронизация, значит XML-RPC был нужен. Проверьте интеграции и либо оставьте доступ, либо перенесите интеграцию на REST API.
Сделали блокировку только в WordPress, но забыли про серверный кеш
Если перед сайтом стоит кеширующий слой или CDN, старые ответы могут продолжать отдаваться некоторое время. После правок очистите кеш на всех уровнях: плагин кеша, сервер, CDN.
Проверяли только главную страницу
Это типичная ошибка. Главная может открываться нормально, а закрытый endpoint при этом остаётся доступным. Проверять нужно именно /xmlrpc.php и нужные REST-маршруты.
Практические советы по безопасности и производительности
Если цель — не просто «что-то отключить», а реально уменьшить шум и нагрузку, действуйте в связке:
- закрывайте ненужные точки входа на уровне сервера;
- не используйте глобальные запреты, если сайт зависит от REST API;
- после изменений очищайте кеш и проверяйте логи;
- не ставьте несколько плагинов, которые делают одно и то же;
- храните изменения в дочерней теме или мини-плагине, а не в основной теме.
Если нужен более широкий набор технических правок для чистки сайта и снижения дублей, иногда удобнее собрать их в одном инструменте вроде Clearfy Pro, но только если вы реально используете его функции и понимаете, что именно отключаете.
Главный критерий успеха здесь простой: нужные интеграции работают, лишние входы закрыты, а в логах больше нет постоянного мусора от запросов, которые сайту не нужны.