Renforcer sécurité WordPress : désactiver l’accès inutilisé à XML-RPC

XML-RPC fait partie de ces sujets que l’on croise en maintenance, puis que l’on laisse de côté jusqu’au jour où un site se retrouve sous scans ou sous tentatives d’authentification en rafale. Le symptôme est souvent discret au début: des pics de logs, une montée des erreurs 401 ou 403, parfois quelques performances dégradées. Ensuite, on découvre que des robots testent inlassablement le même point d’entrée, xmlrpc.php, même quand personne ne l’utilise.

Désactiver l’accès inutilisé à XML-RPC est l’un des gestes les plus simples pour renforcer la sécurité WordPress, surtout sur des sites gérés sans outils externes qui dépendraient de cet endpoint. Ce n’est pas une solution magique, mais c’est un verrou efficace, et en général assez facile à mettre en place sans casser le fonctionnement du site.

Comprendre XML-RPC, et pourquoi il attire les attaques

XML-RPC (XML Remote Procedure Call) permet à WordPress d’échanger avec des clients distants, via un protocole basé sur des requêtes XML. Historiquement, c’était pratique pour la publication à distance, certains connecteurs de blogs, ou l’accès depuis des applications plus anciennes.

Le problème, c’est que, dès qu’un endpoint est accessible publiquement, il devient une cible. Beaucoup d’attaques automatisées ne cherchent pas un “exploit” sophistiqué au départ. Elles testent la surface d’attaque, elles provoquent des erreurs, elles tentent des identifiants, et elles mesurent la réponse. xmlrpc.php se retrouve dans ces chemins de test car il répond de façon spécifique et il est souvent connu des scanners.

Sur un site où XML-RPC n’est pas réellement nécessaire, le meilleur choix de sécurité consiste souvent à supprimer le “chemin” lui-même. Moins d’accès, moins de bruit dans les journaux, moins de tentatives inutiles. Et quand on renforce la sécurité WordPress, on gagne aussi en visibilité: si xmlrpc.php ne répond plus, les tentatives associées disparaissent, ce qui rend les incidents plus faciles à identifier.

Le piège de la suppression “à l’aveugle”

Le seul point de vigilance, c’est la compatibilité. Désactiver XML-RPC peut impacter des usages légitimes que l’on n’avait pas anticipés:

    un plugin qui s’appuie dessus, une application mobile ou un outil de publication, une intégration externe qui utilise l’endpoint, parfois des automatisations historiques.

Dans une migration, j’ai vu le cas typique: un site “classique” où XML-RPC était désactivé, puis quelqu’un s’est plaint que la publication depuis une ancienne application mobile ne fonctionnait plus. Le site tournait, mais un canal important avait été oublié. Résultat: on a réactivé temporairement pour diagnostiquer, puis on a remplacé l’intégration par une méthode plus moderne.

L’idée n’est pas de rester paralysé. L’idée, c’est de vérifier avant, ou de prévoir une validation après.

Vérifier si XML-RPC est réellement utilisé chez vous

Avant de couper, prenez quelques minutes pour regarder ce que vous avez réellement en place. Ce travail évite de transformer un gain sécurité en régression produit.

Vous pouvez vous baser sur trois axes, simples:

1) Observer vos logs et vos alertes: si vous voyez surtout des requêtes robotisées sans trafic “humain”, c’est un bon indicateur que la fonctionnalité n’est pas exploitée régulièrement.

2) Inventorier les composants: plugins, intégrations, et outils d’authentification ou de publication. Un plugin de sauvegarde, un connecteur “multi-site”, ou une passerelle de blog peut parfois s’appuyer sur des appels distants.

3) Regarder votre mode d’usage: publiez-vous uniquement depuis l’interface WordPress? Utilisez-vous une application externe pour poster, prévisualiser ou gérer des contenus?

À ce stade, vous n’avez pas besoin d’être certain à 100 pour cent. En maintenance, on vise surtout une décision raisonnable. Si vous êtes dans un cas “faible risque fonctionnel”, la désactivation est souvent une victoire rapide.

Choisir la bonne méthode de désactivation

Il existe plusieurs manières de désactiver XML-RPC. La meilleure approche dépend de votre stack (Apache, Nginx), de votre hébergement (accès aux fichiers de configuration, restrictions), et de vos exigences (zéro appel autorisé, retour d’erreur, redirection, etc.).

Voici les options courantes, avec leurs implications.

    Bloquer xmlrpc.php au niveau du serveur (Apache via .htaccess, Nginx via règles). C’est généralement la méthode la plus robuste, car le code WordPress n’est même pas exécuté. Utiliser un plugin de sécurité qui désactive XML-RPC. Pratique, mais dépend du plugin et de sa maintenance. Filtrer côté WordPress via un bout de code (par exemple dans un mu-plugin ou un thème). Cela marche, mais le endpoint reste atteignable, et WordPress est chargé avant de refuser. Désactiver “partiellement” en laissant l’endpoint accessible pour certains cas, si vous devez conserver une compatibilité minimale. C’est plus fin, mais aussi plus fragile à maintenir.

Dans la majorité des installations, bloquer au niveau serveur est le meilleur compromis. Vous réduisez la surface d’attaque tout en simplifiant la logique applicative.

Désactiver XML-RPC avec Apache (via .htaccess)

Si votre site fonctionne avec Apache et que vous avez la main sur .htaccess, la solution la plus directe consiste à refuser l’accès à xmlrpc.php.

L’objectif est d’obtenir une réponse stable et non “tentante”. Selon votre configuration, vous pouvez obtenir un code 403 (interdit) ou un 404 (introuvable). Les deux sont acceptables en sécurité. Le 404 peut réduire la divulgation, le 403 bloque clairement.

Exemple typique (à adapter, et à tester en staging):

Require all denied

Sur certaines configurations plus anciennes, on utilise plutôt Order allow,deny et Deny from all. Comme je ne sais pas votre version serveur, gardez en tête que la syntaxe peut varier.

Attention aux réécritures et à l’ordre des règles

Quand il y a un mod_rewrite actif, les règles peuvent interférer. Après modification, vérifiez que xmlrpc.php est bien coupé. Dans les logs d’accès, vous voulez voir des demandes qui se terminent rapidement, sans traces d’exécution WordPress.

Désactiver XML-RPC avec Nginx

Avec Nginx, l’approche est similaire: bloquer spécifiquement xmlrpc.php. Souvent, cela ressemble à une règle dans le bloc server.

Exemple conceptuel (à adapter selon votre structure de configuration):

Location = /xmlrpc.php Return 403;

Selon vos préférences, vous pouvez retourner 404. Le plus important est d’être cohérent et de ne pas laisser l’endpoint accessible “par erreur” via une autre route ou un alias.

image

Bien valider derrière un reverse proxy

Si vous êtes derrière un load balancer ou un reverse proxy (ou si vous avez Cloudflare et autre couche), assurez-vous que la requête aboutit bien sur la règle. Parfois, la requête arrive au proxy et est traitée avant d’atteindre Nginx, ce qui change les codes visibles dans vos journaux. Ce n’est pas forcément un problème, mais gardez-le en tête lors de votre validation.

Désactiver via plugin: pratique, mais à encadrer

Utiliser un plugin peut être intéressant si vous n’avez pas accès à la configuration serveur, ou si vous voulez piloter plusieurs réglages de sécurité depuis l’interface.

Le point essentiel, c’est de ne pas installer un “usine à gaz” pour un geste simple. Vérifiez:

    que le plugin désactive bien xmlrpc.php, comment il le fait, au niveau serveur ou via un refus applicatif, comment tester le résultat sans ambiguïté, et comment revenir en arrière si besoin.

Je préfère, quand c’est possible, une règle serveur. Cela reste le choix le plus “définitif”. Mais sur un hébergement partagé très contraint, le plugin peut être la voie la plus réaliste.

Désactiver dans WordPress: quand vous n’avez vraiment pas d’autre choix

Vous pouvez aussi refuser l’accès dans WordPress. L’idée est d’ajouter un contrôle dans un point d’entrée, typiquement via un hook, ou via un plugin mu-plugin chargé au démarrage.

Je le déconseille en première intention pour une raison simple: WordPress sera quand même chargé avant de refuser. En sécurité, ce n’est pas dramatique en soi, mais cela garde une partie du traitement accessible. Cela peut aussi compliquer les performances si les tentatives automatisées sont nombreuses.

image

image

Si vous passez par cette option, le bon critère est la cohérence du refus: un 403 propre, sans laisser WordPress exécuter inutilement des chemins.

Impact fonctionnel: ce que vous pouvez casser, et comment éviter la mauvaise surprise

Désactiver XML-RPC n’impacte pas le front du site. Le risque concerne surtout les outils d’administration à distance et certaines intégrations.

Les cas typiques de “surprise” sont:

    une application mobile ou un client ancien configuré pour poster via XML-RPC, un workflow de publication automatisé qui utilisait ce protocole, des plugins moins fréquents, qui appellent directement l’endpoint.

La manière la plus saine de limiter le risque consiste à tester avant et après:

    Testez un flux d’administration réel (connectez-vous, publiez un brouillon si c’est votre usage). Surveillez les logs pendant 24 à 48 heures après la coupure. Si vous voyez que certains services tentent toujours des requêtes XML-RPC, vous saurez au moins ce que vous coupez, et vous pourrez décider de remplacer l’intégration plutôt que de réouvrir.

Une anecdote réelle, sur un site d’association: la désactivation a provoqué l’arrêt d’un outil qui importait des articles depuis un autre système. La demande venait de manière régulière, mais l’équipe n’avait pas relié le fonctionnement à XML-RPC. Le diagnostic a pris du temps, car les erreurs n’étaient pas visibles côté site. Le vrai apprentissage a été de documenter les dépendances, même quand elles “semblent” mineures.

Contrôler que la désactivation fonctionne vraiment

Après la mise en place, il faut valider. Le test idéal n’est pas “ça semble bloqué”, mais “je sais ce que renvoie le serveur”.

Vous pouvez procéder de façon pragmatique:

    ouvrir https://votre-domaine.tld/xmlrpc.php dans le navigateur et observer le code, vérifier dans les logs d’accès que les requêtes se terminent avec un refus immédiat, surveiller le trafic sur les 2 jours suivants, surtout si vous aviez déjà des scanners.

Petit protocole de validation (rapide)

Coupez l’accès à xmlrpc.php selon votre méthode (serveur ou WordPress). Testez depuis une machine externe, pas depuis le même poste que l’admin. Contrôlez le code HTTP renvoyé (403 ou 404, selon votre règle). Vérifiez les logs, idéalement avec un filtre sur xmlrpc.php. Surveillez les erreurs liées à l’administration ou aux intégrations pendant 24 à 48 heures.

Si vous observez que des systèmes internes ont besoin de XML-RPC, vous avez un signal pour corriger, plutôt que de masquer le problème.

Ce que la désactivation de XML-RPC ne règle pas

C’est important pour ne pas tomber dans le “tout ou rien”. Couper XML-RPC réduit une surface d’attaque, mais ne remplace pas une stratégie globale.

Vous aurez toujours:

    des tentatives sur /wp-login.php, des scans de plugins et thèmes, des attaques sur des endpoints REST si exposés, et des tentatives sur des pages de fichiers ou de sauvegardes.

Donc, même après la désactivation, gardez votre hygiène sécurité. Mettre l’accent sur la limitation du brute force, les mises à jour régulières, et la réduction de l’exposition des informations reste essentiel.

Edge cases: quand vous devez faire preuve de nuance

Il y a des cas où couper XML-RPC peut être trop agressif sans investigation. Par exemple:

    vous avez un outil tiers non documenté qui “publie automatiquement”, vous n’avez pas la visibilité sur les intégrations historiques, votre équipe a changé et personne ne sait comment ça marchait.

Dans ces situations, je conseille souvent une approche progressive: d’abord observer les logs, identifier les sources qui touchent xmlrpc.php, puis planifier un remplacement de l’intégration plutôt qu’un arrêt brut.

Autre nuance: certains environnements autorisent XML-RPC seulement depuis des IP spécifiques (réseaux d’admin, bastion, ou VPN). Si votre infrastructure le permet, c’est un compromis utile, mais il faut maîtriser la gestion des IP et des accès. Un “compromis” mal cadré finit parfois par devenir une ouverture permanente.

Journalisation et signalement: ce qui améliore la sécurité au-delà du blocage

Quand vous bloquez xmlrpc.php, vous gagnez du calme dans les logs, mais vous gagnez aussi en diagnostic. Si vous gardez une journalisation minimale, vous pouvez corréler:

    les changements de règles, les pics de requêtes, les erreurs de backend ou d’intégrations.

Sur un site récemment audité, la désactivation de XML-RPC a été le premier levier. Le vrai gain, ensuite, a été la mise en place d’un https://gardewp.fr/securite-wordpress/ suivi simple: un tableau de bord des codes HTTP majeurs sur les endpoints sensibles. On a pu constater que les tentatives sur /wp-login.php continuaient, et que le volume restait stable. Résultat: au lieu de re-attaquer sans fin, on a ciblé la suite du durcissement.

Recommandations pratiques pour “renforcer la sécurité WordPress” autour de XML-RPC

Désactiver XML-RPC n’est qu’une partie du travail. Pour que le geste serve vraiment votre objectif, je recommande de l’inscrire dans une routine, pas dans un événement ponctuel.

Voici comment je raisonne en atelier:

    mettre à jour WordPress, thèmes et plugins avant de changer des règles d’accès, réduire la surface d’exposition (et donc l’“attirance” des scanners), renforcer l’authentification côté administration (limitation du brute force, comptes avec droits minimaux), et surtout vérifier que les usages métiers fonctionnent après changement.

La conséquence intéressante, c’est que votre sécurité devient moins dépendante de “surprises”. Vous réduisez la probabilité que quelqu’un réactive un endpoint par accident parce qu’un outil a cessé de fonctionner. Vous gagnez une forme de stabilité opérationnelle.

Une stratégie simple si vous voulez avancer sans stress

Si vous devez choisir une approche sans y passer une semaine, voici le scénario le plus fréquent:

1) Vous vérifiez rapidement s’il y a une dépendance (plugins, intégrations, habitudes d’administration). 2) Vous coupez xmlrpc.php au niveau serveur si possible. 3) Vous validez avec tests et observation des logs. 4) Vous surveillez 24 à 48 heures. 5) Si quelque chose casse, vous remplacez l’intégration plutôt que de réouvrir en grand.

Ce n’est pas spectaculaire, mais c’est efficace. Et dans le durcissement WordPress, c’est souvent la constance qui fait la différence.

Si vous me dites votre environnement (Apache ou Nginx, hébergement partagé ou VPS, présence d’un reverse proxy, et si vous utilisez des applications tierces pour publier), je peux vous proposer la règle la plus adaptée, avec une logique de test et de rollback pour éviter la mauvaise surprise.