XML-RPC в WordPress до сих пор часто включён по умолчанию, хотя на многих сайтах он не нужен вообще. Проблема в том, что через xmlrpc.php удобно не только подключать внешние клиенты и мобильные приложения, но и массово подбирать пароли, тестировать доступность сайта и создавать лишнюю нагрузку на сервер. Если вы не используете удалённую публикацию, старые мобильные клиенты или специфические интеграции, этот вход лучше закрыть.
Ниже разберём, как понять, нужен ли XML-RPC именно вашему сайту, чем отличается блокировка на уровне WordPress от блокировки на уровне сервера, и как проверить, что после изменений ничего лишнего не сломалось.
Когда XML-RPC действительно стоит отключать
Отключение имеет смысл, если сайт работает как обычный корпоративный блог, медиа-проект или лендинг, а публикация идёт только через админку WordPress. В таком случае XML-RPC чаще приносит риски, чем пользу.
Сценарии, где его обычно не используют
- редакторы заходят только в
/wp-admin/; - нет сторонних сервисов, которые публикуют записи через XML-RPC;
- не используется старое приложение WordPress для iOS/Android;
- нет интеграций с внешними системами, которым нужен метод
metaWeblog.newPostили похожие XML-RPC вызовы.
Когда отключать нельзя без проверки
Если сайт подключён к внешним сервисам автопостинга, использует старые мобильные клиенты или какие-то корпоративные скрипты для публикации, сначала проверьте, чем именно они пользуются. Иногда интеграция выглядит как «обычный API», но по факту ходит именно в xmlrpc.php. В таком случае лучше не рубить доступ вслепую.
Диагностика: как понять, что XML-RPC уже используется
Самый простой способ — посмотреть логи веб-сервера или WAF. Если там регулярно встречаются запросы к /xmlrpc.php, это не всегда атака, но почти всегда сигнал, что endpoint виден снаружи и его активно сканируют.
На уровне WordPress можно быстро проверить, отвечает ли файл вообще:
curl -I https://example.com/xmlrpc.phpЕсли в ответе вы видите 200 или 405, файл доступен. Это нормально для стандартной установки, но не означает, что он нужен вашему проекту.
Ещё один полезный тест — отправить заведомо пустой XML-RPC запрос и посмотреть реакцию:
curl -s -X POST https://example.com/xmlrpc.php \
-H 'Content-Type: text/xml' \
--data '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>'Если сервер возвращает XML-ответ, endpoint активен. Это не ошибка само по себе, но если вы не используете удалённую публикацию, его можно закрывать.
Что лучше: плагин, код или блокировка на сервере
Для разных задач подходят разные способы. Если нужен быстрый и обратимый вариант, удобнее начать с плагина или небольшого кода. Если важна защита от лишних запросов ещё до загрузки WordPress, лучше блокировать на уровне Nginx или Apache.
| Способ | Плюсы | Минусы | Когда выбирать |
|---|---|---|---|
| Плагин безопасности | Быстро включить, не трогая сервер | Дополнительная нагрузка, зависит от плагина | Если нет доступа к конфигу веб-сервера |
| Код в теме или mu-plugin | Просто откатить, не нужен отдельный плагин | WordPress всё равно загружается | Если нужен точечный контроль |
| Nginx/Apache | Блокирует до загрузки WordPress | Нужен доступ к конфигу | Если важна минимальная нагрузка и защита от брутфорса |
Пошаговое решение через код
Если вы хотите отключить XML-RPC без сторонних плагинов, добавьте фильтр в functions.php дочерней темы или, лучше, в небольшой mu-plugin. Для production-сайта mu-plugin надёжнее: его сложнее случайно отключить при смене темы.
<?php
/**
* Plugin Name: Disable XML-RPC
*/
add_filter('xmlrpc_enabled', '__return_false');Этот вариант отключает сам механизм XML-RPC на уровне WordPress. После этого запросы к xmlrpc.php перестанут работать как раньше, а типичные попытки подбора пароля через этот канал потеряют смысл.
Если нужно не отключать полностью, а только ограничить доступ
Иногда удобнее оставить XML-RPC для внутренних задач, но закрыть его для всех остальных. Тогда можно проверять IP и отдавать 403 только для внешних адресов. Такой подход полезен, если у вас есть один известный офисный IP или VPN.
<?php
add_action('init', function () {
if (!defined('XMLRPC_REQUEST') || !XMLRPC_REQUEST) {
return;
}
$allowed_ips = array('203.0.113.10');
$remote_ip = $_SERVER['REMOTE_ADDR'] ?? '';
if (!in_array($remote_ip, $allowed_ips, true)) {
status_header(403);
exit;
}
});Это уже более узкий сценарий. Для обычного сайта такой код избыточен, но для закрытых корпоративных установок он может быть полезен.
Блокировка на уровне Nginx или Apache
Если у вас есть доступ к конфигу сервера, лучше закрыть xmlrpc.php ещё до запуска PHP. Это снижает расход ресурсов и помогает отсеивать шум от сканеров.
Nginx
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
return 444;
}Вместо 444 можно использовать 403, если вам важнее предсказуемый ответ, чем молчаливое закрытие соединения. Но для борьбы с массовыми сканами 444 часто удобнее.
Apache
<Files "xmlrpc.php">
Require all denied
</Files>После правки конфигурации не забудьте перезагрузить веб-сервер и проверить, что правило применяется именно к нужному виртуальному хосту, а не только в тестовой среде.
Как проверить, что решение сработало
Проверка должна быть не только технической, но и функциональной. Сначала убедитесь, что endpoint закрыт, потом проверьте привычные сценарии входа и публикации.
- Откройте
/xmlrpc.phpв браузере или черезcurlи проверьте, что ответ изменился на403,404или другой ожидаемый статус. - Посмотрите логи веб-сервера: количество запросов к
xmlrpc.phpдолжно перестать превращаться в нагрузку на PHP. - Проверьте вход в админку, создание записей, загрузку медиафайлов и работу REST API.
- Если у вас есть внешняя публикация или мобильное приложение, протестируйте именно его.
Для быстрой проверки статуса можно использовать:
curl -I https://example.com/xmlrpc.phpЕсли вы блокировали доступ на уровне WordPress, ответ может быть не таким «чистым», как при серверной блокировке, но сам факт недоступности endpoint уже достаточен.
Частые ошибки и как их исправить
Отключили XML-RPC, а потом перестали работать внешние публикации
Это типичная ситуация, если сайт использует старый клиент или интеграцию, о которой давно забыли. Решение простое: временно верните доступ, найдите источник запросов в логах и переведите интеграцию на другой способ авторизации, если он есть.
Поставили плагин безопасности, но запросы всё равно идут
Не все плагины блокируют endpoint одинаково. Некоторые только ограничивают методы, но не закрывают сам файл. В таком случае лучше проверить настройки плагина или добавить серверное правило.
Сломали XML-RPC, но забыли про кэш и CDN
Если перед сайтом стоит CDN или reverse proxy, старые ответы могут какое-то время сохраняться. После изменений очистите кэш на всех уровнях: плагин кэша, серверный кэш, CDN.
Добавили код в активную тему и потеряли его после обновления
Для технических ограничений лучше использовать mu-plugin или отдельный мини-плагин. Это проще сопровождать и безопаснее для обновлений темы.
Практические советы по безопасности и производительности
Отключение XML-RPC — не замена нормальной защите входа. Если у вас слабые пароли или нет ограничений на /wp-login.php, один закрытый endpoint проблему не решит.
- используйте сложные пароли и двухфакторную аутентификацию для админов;
- ограничивайте попытки входа, если это уместно для проекта;
- следите за логами 403/404 по
xmlrpc.php— это хороший индикатор сканирования; - не держите лишние плагины, которые тоже открывают внешние точки входа без необходимости;
- после отключения проверьте, не осталось ли в документации проекта старых инструкций по XML-RPC.
Если вам нужно не только закрыть XML-RPC, но и убрать лишние технические дубли, мусорные мета-данные и другие SEO-артефакты, имеет смысл смотреть на комплексную чистку сайта. В таких задачах удобно использовать Clearfy Pro, но только если его функции действительно закрывают ваши конкретные проблемы, а не ставятся «на всякий случай».
В сухом остатке: если XML-RPC вам не нужен, отключайте его на уровне сервера или через xmlrpc_enabled, а потом обязательно проверьте реальные сценарии публикации и интеграций. Так вы уберёте лишнюю точку атаки и не сломаете рабочие процессы.