Как ограничить XML-RPC запросы в WordPress без полного отключения сервиса

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

Ниже — рабочий сценарий: сначала понять, кто и зачем обращается к xmlrpc.php, затем оставить нужное и закрыть лишнее. Такой подход полезен, если сайт уже живёт с интеграциями и ломать их нельзя.

Когда XML-RPC действительно мешает

Проблема обычно проявляется не в самом файле xmlrpc.php, а в том, что через него идут массовые запросы, брутфорс или лишние вызовы от старых интеграций. Если в логах много обращений к /xmlrpc.php, а в панели безопасности видны попытки подбора логина, это повод не отключать всё подряд, а ограничить поверхность атаки.

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

  • есть ли мобильное приложение WordPress у редакторов;
  • используются ли внешние сервисы публикации или автопостинга;
  • подключён ли старый клиент бэкапов, который работает через XML-RPC;
  • есть ли в логах повторяющиеся POST-запросы к xmlrpc.php с одного IP;
  • не блокирует ли хостинг этот файл на уровне WAF уже сейчас.

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

Диагностика: кто обращается к xmlrpc.php

Сначала посмотрите access-логи веб-сервера. Для Nginx это обычно /var/log/nginx/access.log, для Apache — аналогичный access-log. Ищите строки с xmlrpc.php. Если запросы идут часто и одинаково, это уже не рабочая интеграция, а шум или атака.

grep "xmlrpc.php" /var/log/nginx/access.log | tail -n 50

Если у вас нет доступа к логам сервера, можно временно добавить простую запись в error_log на уровне WordPress и посмотреть, какие методы вызываются. Это не замена нормальному логированию, но для короткой диагностики подходит.

add_filter('xmlrpc_enabled', function ($enabled) {
    if (defined('WP_DEBUG') && WP_DEBUG) {
        error_log('XML-RPC requested from: ' . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
    }
    return $enabled;
});

Этот код не ограничивает доступ, а только помогает понять, что происходит. Для постоянной работы он не нужен.

Пошаговое решение: ограничиваем XML-RPC, а не ломаем его

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

ПодходКогда подходитКомпромисс
Блокировка на сервереXML-RPC не используется вообщеНичего через него работать не будет
Ограничение методов в WordPressНужны только отдельные функцииНужно поддерживать код в теме или mu-plugin
WAF / rate limitЕсть атаки, но сервис нуженТребует настройки на стороне хостинга

Вариант 1. Оставить только нужные методы

Если вам нужен, например, только постинг из внешнего клиента, можно вырезать лишние методы через фильтр xmlrpc_methods. Это безопаснее, чем отключать сервис целиком.

add_filter('xmlrpc_methods', function ($methods) {
    $allowed = array(
        'wp.getUsersBlogs'   => $methods['wp.getUsersBlogs'] ?? null,
        'wp.newPost'         => $methods['wp.newPost'] ?? null,
        'wp.editPost'        => $methods['wp.editPost'] ?? null,
        'wp.deletePost'      => $methods['wp.deletePost'] ?? null,
        'wp.uploadFile'      => $methods['wp.uploadFile'] ?? null,
    );

    return array_filter($allowed);
});

Смысл простой: вы не даёте XML-RPC полный набор возможностей, а оставляете только те методы, которые реально нужны редакции. Перед внедрением обязательно проверьте, какие методы использует ваш клиент.

Вариант 2. Закрыть доступ к xmlrpc.php на уровне сервера

Если XML-RPC не нужен вообще, лучше блокировать запросы до WordPress. Это дешевле для производительности и надёжнее для безопасности.

Для Nginx можно добавить отдельное правило:

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

Для Apache обычно используют правило в .htaccess:

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

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

Вариант 3. Ограничить частоту запросов

Если сервис нужен, но идёт поток мусорных запросов, имеет смысл включить rate limiting на уровне nginx, Cloudflare или другого WAF. Это не WordPress-решение, но в реальности именно оно лучше всего режет брутфорс по xmlrpc.php.

На стороне WordPress можно дополнительно ограничить доступ по IP, если интеграция работает с фиксированного адреса:

add_action('init', function () {
    if (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) {
        $allowed_ips = array('203.0.113.10');
        $remote_ip = $_SERVER['REMOTE_ADDR'] ?? '';

        if (!in_array($remote_ip, $allowed_ips, true)) {
            status_header(403);
            exit;
        }
    }
});

Это уже более жёсткий сценарий. Он подходит для корпоративных интеграций, но плохо совместим с мобильными клиентами и сервисами с плавающими IP.

Как проверить, что ограничение сработало

После изменений проверьте не только безопасность, но и рабочие сценарии. Иначе можно случайно отрезать редакцию от публикации материалов.

  • Откройте /xmlrpc.php в браузере — при серверной блокировке должен быть отказ в доступе или пустой ответ без выполнения WordPress.
  • Попробуйте отправить тестовый пост из того клиента, который реально используется.
  • Посмотрите access-лог: число запросов к xmlrpc.php должно снизиться или исчезнуть.
  • Проверьте, не появились ли ошибки авторизации в мобильном приложении или внешнем сервисе.
  • Убедитесь, что другие функции сайта не затронуты — XML-RPC не должен влиять на обычный вход в админку.

Если вы ограничивали методы через xmlrpc_methods, протестируйте именно те действия, которые нужны: публикацию записи, редактирование и загрузку медиа. Если метод вырезан, клиент обычно покажет ошибку авторизации или недоступности метода.

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

Полное отключение без проверки интеграций

Самая частая ошибка — сразу рубить xmlrpc.php на сервере, не проверив, кто им пользуется. В результате ломаются мобильные приложения, автопостинг или старые инструменты синхронизации. Исправление простое: сначала инвентаризация, потом блокировка.

Ограничение только через плагин безопасности

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

Слишком широкий whitelist по IP

Если вы разрешили целую подсеть «на всякий случай», защита становится формальной. Для внешних сервисов лучше фиксировать конкретные адреса или использовать WAF-правила с более точной логикой.

Забыли про кэш и CDN

Иногда после изменения правил старые ответы продолжают отдаваться через CDN или reverse proxy. Если проверка показывает, что xmlrpc.php всё ещё доступен, очистите кэш на всех уровнях: WordPress, сервер, CDN.

Практика безопасности и производительности

Если XML-RPC не нужен, блокировка на сервере — самый чистый вариант: меньше лишних PHP-запусков, меньше точек атаки, меньше шума в логах. Если нужен, не оставляйте его открытым «как есть» — хотя бы ограничьте методы и добавьте rate limit.

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

Главный критерий здесь не «отключено или нет», а «какие именно сценарии остались рабочими». Если редакция может публиковать контент, а лишние запросы больше не проходят, задача решена правильно.

⭐⭐⭐⭐⭐