Как отключить XML-RPC в WordPress без поломки сайта

XML-RPC в WordPress до сих пор встречается на живых сайтах, хотя для большинства проектов он не нужен. Проблема в том, что его часто отключают «на всякий случай», а потом ломают мобильные приложения, внешние публикации или старые интеграции. Если задача не абстрактная, а практическая, сначала нужно понять, используется ли endpoint /xmlrpc.php вообще.

Когда XML-RPC действительно стоит отключать

На обычном сайте без внешних сервисов XML-RPC чаще всего не нужен. Исторически он использовался для удалённой публикации, pingback и некоторых старых клиентов. Сейчас у WordPress есть REST API, и большинство современных интеграций работают через него. Но это не значит, что XML-RPC можно выключить без проверки.

Отключение оправдано, если:

  • сайт не использует мобильные приложения WordPress для публикации;
  • нет внешних сервисов, которые отправляют записи через XML-RPC;
  • не нужны pingback и trackback;
  • вы хотите убрать лишнюю поверхность атаки, особенно если на сайте уже были попытки брутфорса.

Если хотя бы один внешний клиент работает через XML-RPC, сначала найдите его и переведите на REST API или другой способ интеграции.

Диагностика: используется ли xmlrpc.php на вашем сайте

Самая частая ошибка — отключить endpoint, не проверив логи и интеграции. Начните с простых признаков. Если в логах веб-сервера есть регулярные запросы к /xmlrpc.php, это уже сигнал. Если вы видите ответы с кодом 200 или 403 на этот путь, endpoint доступен и его кто-то дергает.

Что проверить вручную

  • логи Nginx или Apache на запросы к xmlrpc.php;
  • настройки мобильных клиентов WordPress;
  • интеграции с внешними сервисами, которые публикуют записи;
  • наличие плагинов для удалённой публикации или старых синхронизаций.

Можно быстро проверить сам endpoint через curl:

curl -I https://example.com/xmlrpc.php

Если сервер отвечает не 404, значит файл доступен. Это ещё не доказывает, что он нужен, но показывает, что его можно атаковать или использовать.

Как отключить XML-RPC: три рабочих способа

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

СпособКогда подходитКомпромисс
Код в functions.php или mu-pluginНужен контроль внутри WordPressЗапрос всё равно доходит до WordPress
Блокировка на сервереНужно отрезать endpoint раньше PHPНадо править конфиг Nginx/Apache
Плагин безопасностиНужен быстрый интерфейсЛишняя зависимость от плагина

Способ 1. Отключить XML-RPC через код

Самый аккуратный вариант — добавить фильтр xmlrpc_enabled. Он отключает XML-RPC штатно, без редиректов и костылей. Лучше не вставлять это в активную тему, а использовать mu-plugin, чтобы настройка не пропала при смене темы.

<?php
/**
 * Plugin Name: Disable XML-RPC
 */
add_filter( 'xmlrpc_enabled', '__return_false' );

Если нужен более жёсткий вариант, можно прервать запрос раньше и вернуть 403:

<?php
add_action( 'init', function () {
    if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
        status_header( 403 );
        exit;
    }
}, 1 );

Первый способ обычно достаточно. Второй имеет смысл, если вы хотите явно блокировать обращение к endpoint даже при нестандартной обработке.

Способ 2. Закрыть xmlrpc.php на уровне сервера

Если у вас есть доступ к конфигу веб-сервера, лучше отрезать запрос до запуска PHP. Это снижает нагрузку и убирает лишнюю обработку. Для Nginx правило обычно выглядит так:

location = /xmlrpc.php {
    deny all;
    access_log off;
    log_not_found off;
}

Для Apache можно использовать правило в .htaccess:

<Files xmlrpc.php>
    Require all denied
</Files>

Если сайт работает за CDN или прокси, проверьте, не кэшируется ли ответ на этот путь отдельно. Иначе можно получить странное поведение, когда блокировка уже включена, а старый ответ ещё отдается из промежуточного слоя.

Способ 3. Использовать плагин безопасности

Если на сайте уже стоит плагин для hardening, проверьте, есть ли в нём опция отключения XML-RPC. Это удобно для админов без доступа к серверу, но важно понимать, что плагин не должен быть единственной точкой защиты, если сайт критичный. При миграции или отключении плагина настройка может исчезнуть.

Пошаговое решение без риска для интеграций

  1. Проверьте, есть ли обращения к /xmlrpc.php в логах за последние дни.
  2. Сверьте список внешних сервисов и клиентов, которые могут публиковать записи.
  3. Если интеграций нет, добавьте отключение через xmlrpc_enabled или серверное правило.
  4. Очистите кэш страницы и кэш на уровне CDN, если он есть.
  5. Проверьте ответ endpoint после изменения.

Если вы не уверены, начните с фильтра xmlrpc_enabled. Его проще откатить, чем серверную блокировку, и он хорошо подходит для теста на staging-среде.

Как проверить, что XML-RPC действительно отключён

Проверка должна быть не «на глаз», а по факту ответа сервера. Самый простой способ — повторить запрос к endpoint и посмотреть код ответа. После отключения вы должны получить 403, 404 или другой контролируемый отказ, в зависимости от выбранного метода.

curl -I https://example.com/xmlrpc.php

Если вы отключали через xmlrpc_enabled, можно также проверить поведение через XML-RPC-клиент или отправить тестовый запрос методом system.listMethods. Важно не только увидеть запрет, но и убедиться, что обычные функции сайта не пострадали: вход в админку, REST API, публикация записей, работа форм и кэша.

Что должно остаться рабочим

  • вход в /wp-admin/;
  • REST API на /wp-json/;
  • публикация и редактирование записей в админке;
  • интеграции, которые используют REST API, а не XML-RPC;
  • кэширование страниц и объектов.

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

Отключили XML-RPC, а мобильное приложение перестало публиковать

Значит, у вас был реальный клиент, который использовал XML-RPC. Решение — либо вернуть endpoint, либо перевести публикацию на другой механизм. Не отключайте его без анализа логов и пользователей.

Поставили правило в .htaccess, но xmlrpc.php всё равно отвечает

Часто это происходит на Nginx, где .htaccess вообще не работает. Либо правило не попало в активный виртуальный хост, либо запрос обрабатывается другим слоем. Проверьте конфигурацию именно того веб-сервера, который обслуживает сайт.

Сайт начал отдавать 500 после правки functions.php

Обычно причина в синтаксической ошибке или в том, что код вставили в активную тему, а потом обновили её. Для таких настроек безопаснее использовать mu-plugin. Тогда отключение не потеряется и не сломается при смене шаблона.

Проверили только в браузере и решили, что всё отключено

Браузерный тест недостаточен. Некоторые плагины или прокси могут маскировать ответ. Проверяйте через curl и, если нужно, через реальный XML-RPC-запрос.

Безопасность и производительность: что ещё стоит учесть

Отключение XML-RPC не заменяет нормальную защиту входа. Если у вас слабые пароли, нет ограничения попыток входа и не настроена двухфакторная аутентификация, проблема брутфорса останется. Но убрать лишний endpoint всё равно полезно: это сокращает поверхность атаки и убирает ненужную обработку запросов.

Если сайт под нагрузкой, серверная блокировка предпочтительнее PHP-фильтра. Она дешевле по ресурсам и не нагружает WordPress на каждом обращении к xmlrpc.php. Для небольшого сайта разница может быть незаметна, но на атакуемом проекте это уже имеет значение.

Если вам нужен набор базовых технических настроек для WordPress, имеет смысл держать их в одном месте и не размазывать по теме и плагинам. В таких случаях удобно использовать отдельный mu-plugin или системный hardening-плагин, а не править код вручную на каждом обновлении.

⭐⭐⭐⭐⭐