Aller au contenu

IT/TechCybersécurité

XML-RPC PHP : à quoi sert xmlrpc.php et faut-il le désactiver ?

Romain Frutos
Par Romain Frutos
Ordinateur portable ouvert sur un terminal, posé à côté d'une baie de serveurs dans une salle technique

Votre scanner de sécurité signale xmlrpc.php, ou vos journaux montrent des rafales de requêtes POST vers ce script XML-RPC PHP de WordPress. Si aucun outil du site ne s’en sert, on le bloque au niveau du serveur ; si Jetpack en dépend, on le bloque pour tous sauf pour ses adresses IP.

Vous avez déjà collé la ligne xmlrpc_enabled d’un tutoriel ? Elle ne suffit pas, car elle laisse ouverts les pingbacks, ceux qui font de votre site un relais.

XML-RPC, c’est quoi et que fait xmlrpc.php ?

Mains sur un clavier à côté d'un carnet ouvert montrant un schéma client-serveur dessiné à la main avec deux flèches

XML-RPC est un protocole d’appel de procédure à distance, plus ancien que les API REST. Le client envoie en HTTP POST un court document XML qui nomme une méthode et ses paramètres, et le serveur répond dans le même format.

Dans WordPress, les applications passaient par xmlrpc.php, avant l’API REST, pour publier un article, téléverser une image, gérer les commentaires… Le fichier reste actif par défaut et ne se règle plus que par du code, depuis que la version 3.5 a retiré son option de l’administration.

Avec l’appel wp.getUsersBlogs, le client glisse identifiant et mot de passe dans le XML et reçoit la liste des sites du compte ; chaque requête permet donc d’essayer un mot de passe.

Cela dit, sur la plupart des sites, xmlrpc.php est une porte ouverte que personne n’emprunte, sauf ceux qui la cherchent. Il tourne avec IXR, la bibliothèque interne de WordPress, sans l’extension PHP xmlrpc ; notre article sur les différences entre API et web services situe XML-RPC face aux API REST.

Faut-il désactiver XML-RPC sur WordPress ?

Porte de service entrouverte dans un couloir de bureaux, avec un badge posé sur le lecteur d'accès

Oui, sauf si vous pouvez nommer l’outil qui s’en sert. La réponse par défaut est de bloquer, et seul Jetpack justifie couramment de garder le fichier joignable, pour ses propres adresses.

Ce qui passe encore par xmlrpc.php

Avant de couper, il suffit de comparer vos outils connectés à cette liste :

  • Jetpack, relié à WordPress.com par ce fichier ;
  • les pingbacks et rétroliens entre blogs, via pingback.ping ;
  • les vieux logiciels de publication de bureau, comme Windows Live Writer ;
  • d’anciens services et applications tiers.

L’éditeur de blocs et l’administration n’en ont en revanche aucun besoin, et les intégrations récentes passent par l’API REST WordPress. Sans rien de tout cela chez vous, la voie est libre.

Ce que les attaquants en font

Pour la force brute, un robot appelle wp.getUsersBlogs avec un identifiant et un mot de passe, reçoit « Incorrect username or password. » (faultCode 403) en cas d’échec, puis recommence. Cette voie contourne un captcha posé sur la seule page wp-login.php !

D’anciens tutoriels y ajoutent system.multicall, qui empile plusieurs appels dans une requête HTTP pour tester une rafale de mots de passe d’un coup.

Reste pingback.ping, qui fait du site un relais sans qu’aucun mot de passe soit nécessaire. À la demande de l’attaquant, WordPress vérifie un lien vers l’adresse de son choix.

Lancée depuis de nombreux sites vers une même cible, la manœuvre alimente un déni de service. Pointée vers un serveur de l’attaquant, elle révèle l’adresse IP d’origine d’un site caché derrière un CDN. Le sondage des ports d’un réseau interne, décrit par d’anciens tutoriels, ne passe plus par défaut, car le cœur actuel refuse les adresses privées.

Comment vérifier si XML-RPC est activé ?

Votre navigateur affiche « XML-RPC server accepts POST requests only. » sur https://votresite.fr/xmlrpc.php ? Produit par la bibliothèque IXR avant tout contrôle de WordPress, ce message prouve seulement que le fichier s’exécute, filtres posés ou non.

À l’inverse, une erreur 403 ou 404 signale un blocage par le serveur. La suite n’a rien de sorcier ; deux requêtes POST envoyées avec curl, sur vos seuls sites, disent ce qui reste ouvert.

# 1. Lister les méthodes
curl -s -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>' https://votresite.fr/xmlrpc.php
# pingback.ping dans la liste = pingbacks ouverts

# 2. Se connecter avec de faux identifiants
curl -s -d '<?xml version="1.0"?><methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value><string>test</string></value></param><param><value><string>test</string></value></param></params></methodCall>' https://votresite.fr/xmlrpc.php
# faultCode 405 = connexions fermées, 403 = ouvertes

Pour la seconde requête, un faultCode 405 et le message « XML-RPC services are disabled on this site. » signalent des connexions fermées, un faultCode 403 des connexions ouvertes.

Le nombre 403 désigne donc deux situations opposées ! Renvoyé comme statut HTTP, il signale un fichier bloqué ; lu dans le corps XML, des connexions ouvertes.

Dans les journaux d’accès, des POST répétés vers xmlrpc.php trahissent un robot ; notre guide pour trouver le propriétaire d’une IP aide à identifier les adresses qui reviennent.

Les trois requêtes qui testent xmlrpc.php, du navigateur aux deux requêtes POST qui révèlent pingbacks et connexions ouverts
Source : documentation Jetpack et developer.wordpress.org

Quelle méthode désactive vraiment XML-RPC ?

Les tutoriels proposent un .htaccess ou une extension sans dire ce qui reste ouvert ; or une seule méthode ferme tout avant que PHP n’entre en jeu.

MéthodeConnexions par mot de passepingback.pingRequête traitée par PHPJetpack
Filtre xmlrpc_enabledFermées (faultCode 405)OuvertOuiNon documenté, à tester
Filtre xmlrpc_methods sans pingbacksOuvertesFerméOuiNon documenté, à tester
Les deux filtres ensembleFerméesFerméOuiNon documenté, à tester
Blocage serveur Apache ou nginxFerméesFerméNon, rejet avant PHPConnexion coupée
Blocage serveur avec exception JetpackFermées hors JetpackFermé hors JetpackNon hors JetpackConnexion préservée
Ce que ferme chaque méthode de désactivation

Source : developer.wordpress.org et documentation Jetpack

Le filtre xmlrpc_enabled ne ferme pas tout

La ligne la plus recopiée, add_filter( 'xmlrpc_enabled', '__return_false' );, désactive XML-RPC sur le papier… En pratique, elle ne coupe que les méthodes authentifiées et ignore les pingbacks ainsi que les points d’accès personnalisés sans authentification.

Seul, ce filtre donne une fausse impression de sécurité, puisque la méthode pingback.ping reste utilisable comme relais et figure toujours dans la réponse à system.listMethods.

Retirer les pingbacks avec xmlrpc_methods

Le filtre xmlrpc_methods retire des méthodes de la liste du serveur. Appliqué aux deux méthodes de pingback et combiné à xmlrpc_enabled, il ferme les deux voies d’abus en laissant le fichier joignable. Placé dans un mu-plugin plutôt que dans le functions.php, il survit à un changement de thème.

<?php
// wp-content/mu-plugins/xmlrpc-durci.php

// Ferme les méthodes à mot de passe (faultCode 405).
add_filter( 'xmlrpc_enabled', '__return_false' );

// Retire les deux méthodes de pingback.
add_filter( 'xmlrpc_methods', function ( $methods ) {
	unset( $methods['pingback.ping'], $methods['pingback.extensions.getPingbacks'] );
	return $methods;
} );

Décocher les pingbacks dans Réglages > Discussion ne remplace pas ce filtre, car l’option ne vaut que pour les nouveaux articles et la méthode reste listée. Vous utilisez Jetpack ? Sa compatibilité avec ces deux filtres n’est pas documentée, d’où l’intérêt de vérifier la connexion ensuite.

Bloquer le fichier sur le serveur

Sans Jetpack, le blocage serveur rejette la requête avant même que PHP ne démarre, ce qui épargne aussi le processeur pendant les vagues d’attaque. C’est l’option à retenir dès lors que rien ne dépend du fichier. Sous Apache 2.4, ces lignes vont dans le .htaccess à la racine du site.

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

Sous nginx, la règle se place dans le bloc server du site.

location = /xmlrpc.php {
    deny all;
}

Vous n’avez pas la main sur la configuration du serveur ? L’hébergeur ou le pare-feu applicatif peut poser la règle, un point à vérifier pour choisir un hébergeur web.

Avec Jetpack, le même blocage s’assortit d’une exception pour ses adresses, et le reste du monde trouve porte close.

XML-RPC PHP : peut-on encore s’en servir en PHP 8 ?

Poste de développeur en open space avec deux écrans de code, une tasse et un carnet de notes ouvert

Oui, mais plus avec l’extension native. Depuis PHP 8.0, l’extension xmlrpc (xmlrpc_encode_request(), xmlrpc_decode()) a quitté la distribution pour PECL, le dépôt des extensions à installer à part.

La RFC du retrait invoque l’abandon de la bibliothèque C sous-jacente, et le paquet PECL n’est plus maintenu. De fait, un vieux script s’arrête net en erreur fatale après la montée de version.

<?php
// Avant : PHP 7.4 avec l'extension xmlrpc
$request = xmlrpc_encode_request('system.listMethods', []);
// PHP 8 : Fatal error, Call to undefined function xmlrpc_encode_request()

// Après : bibliothèque phpxmlrpc (composer require phpxmlrpc/phpxmlrpc)
require 'vendor/autoload.php';

$client = new PhpXmlRpc\Client('https://votresite.fr/xmlrpc.php');
$response = $client->send(new PhpXmlRpc\Request('system.listMethods'));

Deux sorties existent, une bibliothèque en PHP pur comme phpxmlrpc, installée avec Composer, ou un XML construit à la main et envoyé par un client HTTP. WordPress n’est toutefois pas concerné, IXR se passant de l’extension.

Côté XML-RPC Odoo, les points d’accès /xmlrpc/2/common et /xmlrpc/2/object sont dépréciés depuis Odoo 19, et leur retrait est programmé pour Odoo 22, à l’automne 2028. Odoo Online sera touché le premier, avec la version 21.1 prévue à l’hiver 2027 !

La relève s’appelle JSON-2, authentifiée par une clé d’API dans l’en-tête Authorization. En PHP 8, XML-RPC ne se justifie plus que face à un système qui n’offre rien d’autre ; une nouvelle intégration part donc sur JSON-2 chez Odoo, sur l’API REST chez WordPress.

En cas d’échec inexpliqué, un validateur XML-RPC vérifie le message contre la spécification avant qu’on accuse le serveur.

Tout tient à l’outil qui utilise xmlrpc.php sur votre site. S’il n’y en a aucun, le blocage serveur ferme tout ; avec Jetpack, c’est le même blocage avec une exception pour ses adresses ; avec un vieux client de publication, le seul filtre xmlrpc_methods sans pingbacks fait l’affaire en attendant le passage à l’API REST.

Une fois la règle posée, les deux requêtes POST du test se relancent. Après un blocage serveur, elles reçoivent une erreur 403 ; avec le seul filtre xmlrpc_methods, la liste ne contient plus pingback.ping, et le faultCode 403 reste normal puisque les connexions par mot de passe restent ouvertes.

FAQ - Questions fréquentes

Quelle différence entre PHP et XML ?

PHP est un langage exécuté par le serveur, XML un format de données. Le fichier xmlrpc.php est ainsi un script PHP qui lit et écrit du XML.

Faut-il un plugin pour désactiver XML-RPC ?

Non, quelques lignes dans un mu-plugin ou une règle serveur suffisent. Une extension convient aussi si sa description précise qu’elle retire pingback.ping, pas seulement l’accès par mot de passe.

Quelle différence entre XML-RPC et l’API REST WordPress ?

XML-RPC n’a qu’un point d’entrée, échange du XML et transmet l’identifiant et le mot de passe à chaque appel authentifié. L’API REST expose une adresse par ressource sous /wp-json/ et échange du JSON ; c’est elle qu’utilisent les intégrations récentes.

Bloquer xmlrpc.php suffit-il contre la force brute ?

Non, car la page de connexion wp-login.php reste une cible. Des mots de passe solides, la double authentification et un nombre limité de tentatives restent utiles.

Romain Frutos

L'auteur

Romain Frutos

Consultant SEO · Fondateur d'Extenzilla

Il accompagne depuis 6 ans entreprises et agences sur leur visibilité : SEO technique, stratégie sémantique, netlinking, et désormais visibilité dans les moteurs IA.

Tous ses articles LinkedIn

À lire aussi

Vos cookies, votre choix

Avec votre accord, nous mesurons l'audience du site pour savoir quels articles vous intéressent. Aucun traceur n'est activé sans votre accord, et vous pouvez changer d'avis à tout moment. Avec votre accord, nous mesurons l'audience du site. Vous pouvez changer d'avis à tout moment. Politique de cookies

Gérer mes cookies

Choisissez ce que vous acceptez. Votre choix est gardé 6 mois, et vous pouvez le modifier à tout moment avec le lien « Gérer mes cookies », en bas de chaque page.

Fonctionnement du site

Indispensable : retient votre choix de cookies. Ces données ne servent à rien d'autre.

Toujours actif

Google Analytics nous indique quels articles sont lus, sans publicité ni profilage. Les données peuvent être transférées aux États-Unis.

Politique de cookies