Protection brute force WordPress : ce qu'un plugin bloque
Protection force brute WordPress par couches : limitation des connexions, XML-RPC, énumération REST, et pourquoi un plugin ne peut pas arrêter un DDoS.
Aussi en : English Deutsch Español Italiano Polski Português Türkçe
Un plugin de sécurité ralentit efficacement les tentatives de devinette de mots de passe. En revanche, il ne peut rien contre un déluge de trafic. La protection contre la force brute et la protection contre le DDoS sont deux problèmes distincts, traités à des niveaux différents : vos comptes, WordPress lui-même, le serveur web et, en amont, la périphérie du réseau.
Cet article passe en revue les attaques que vous risquez de croiser dans vos journaux : connexions échouées sur wp-login.php, rafales de requêtes sur xmlrpc.php, énumération des utilisateurs via l'API REST et pics de trafic. Pour chacune, il indique la couche qui peut réellement l'arrêter. Chaque mesure est aussi accompagnée d'une ligne sur ce qu'elle ne fait pas.
La protection contre la force brute sur WordPress fonctionne par couches
Le trafic arrive d'Internet et traverse plusieurs couches avant d'atteindre vos données. Plus une requête est stoppée en amont, moins elle vous coûte. Une requête rejetée par un CDN n'atteint jamais votre serveur. Une requête rejetée par un plugin WordPress a déjà consommé une connexion réseau, un processus du serveur web et un worker PHP.
Une correspondance approximative :
| Attaque | Meilleure couche |
|---|---|
| Devinette de mots de passe | Compte (2FA) + plugin |
| XML-RPC multicall | Plugin ou serveur web |
| Énumération REST, scraping | Plugin + périphérie |
| Déluge volumétrique | CDN / périphérie, hébergeur |
Limiter les tentatives de connexion sur wp-login.php
La limitation des connexions compte les échecs et réagit en ajoutant des délais croissants, en bloquant temporairement la source ou en exigeant une vérification. WordPress, de base, n'impose aucune limite. Un attaquant peut tester des mots de passe sur wp-login.php aussi vite que votre serveur répond.
Les limites par adresse IP fonctionnent bien contre une source unique et bruyante. Elles sont moins efficaces contre un botnet qui répartit ses essais sur des milliers d'adresses, chacune restant sous le seuil. C'est pourquoi il faut aussi des limites par nom d'utilisateur. Vingt échecs sur le compte « admin » depuis vingt IP différentes, cela reste un schéma reconnaissable.
Les limites par nom d'utilisateur ont toutefois leur piège. Un verrouillage strict permet à n'importe qui de bloquer votre vrai administrateur en échouant volontairement. Des délais croissants ou une vérification sont plus indulgents qu'un blocage complet.
Deux points décident si la limitation aide ou nuit :
- L'adresse IP du client. Derrière un CDN ou un reverse proxy, toutes les requêtes peuvent sembler venir de l'adresse du proxy. Un plugin qui ne voit que cette adresse limitera tous vos visiteurs en même temps. L'erreur inverse est tout aussi grave : si le plugin fait confiance à l'en-tête
X-Forwarded-Forquelle que soit la provenance, les attaquants peuvent simuler une nouvelle IP à chaque requête et ne sont jamais bloqués. Configurez le plugin, ou le module real-IP du serveur web, pour n'accepter les en-têtes transmis que depuis les plages d'adresses de votre proxy. - Votre propre porte de secours. Placez l'IP de votre bureau sur liste d'autorisation si elle est fixe, et connaissez votre procédure de récupération avant d'en avoir besoin.
Ce que la limitation ne fait pas : elle ne rend pas sûr un mot de passe faible ou réutilisé. Un mot de passe issu d'une fuite de données peut fonctionner dès le premier essai. La vraie solution est un second facteur pour chaque compte à droits élevés, configuré comme dans l'authentification à deux facteurs pour les administrateurs WordPress.
XML-RPC : pourquoi system.multicall transforme une requête en multiples essais
xmlrpc.php est activé par défaut dans WordPress. C'est une ancienne interface de publication à distance, et l'une de ses méthodes, system.multicall, exécute de nombreux appels dans une seule requête HTTP. Un attaquant peut ainsi glisser une longue liste de couples identifiant/mot de passe dans un seul POST.
Cela contourne les protections qui surveillent uniquement wp-login.php ou qui comptent les requêtes. Une seule ligne dans votre journal peut représenter des centaines d'essais. Vérifiez que votre limitation compte aussi les échecs d'authentification XML-RPC, ou supprimez entièrement cette surface d'attaque.
Les pingbacks XML-RPC peuvent en outre être détournés pour faire envoyer des requêtes à des tiers par votre site. Une raison de plus de les désactiver si rien n'en a besoin.
Avant de désactiver XML-RPC : vérifiez ce qui l'utilise encore
Certains outils légitimes communiquent encore avec xmlrpc.php. Parmi eux : d'anciens clients de blogging de bureau et de publication à distance, d'anciennes configurations d'applications mobiles, certains plugins de connexion et des intégrations développées il y a des années. La connexion de Jetpack s'est historiquement appuyée sur XML-RPC ; si vous l'utilisez, consultez sa documentation actuelle.
Commencez par examiner vos journaux d'accès. Sur un serveur Apache ou nginx typique avec le format de journal combined :
# Quelles IP envoient des requêtes POST vers xmlrpc.php ?
grep "POST /xmlrpc.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
# Quels user agents ?
awk -F'"' '/POST \/xmlrpc.php/ {print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
Adaptez le chemin à votre serveur (par exemple /var/log/apache2/access.log) et incluez les journaux archivés. Des milliers de requêtes provenant d'IP changeantes avec des user agents génériques sont des attaques. Quelques requêtes venant d'une seule IP de service connue relèvent probablement d'une intégration : interrogez votre agence ou l'éditeur avant de couper.
Vous avez deux options :
- **Le filtre
xmlrpc_enabled.** Il désactive les méthodes XML-RPC qui exigent une authentification, ce qui stoppe la devinette de mots de passe via XML-RPC. Les méthodes sans authentification, comme les pingbacks, continuent de fonctionner. Voir la référence pour développeurs WordPress. - Bloquer le fichier au niveau du serveur. Cela arrête tout, et PHP ne s'exécute jamais pour ces requêtes.
<Files xmlrpc.php>
Require all denied
</Files>
location = /xmlrpc.php {
deny all;
}
Après la modification, testez la publication, votre application et tout service connecté. Notez ce que vous avez changé et pourquoi, pour que la personne suivante ne le « répare » pas en le remettant.
Énumération des utilisateurs via l'API REST et limitation du trafic anonyme
/wp-json/wp/v2/users liste les utilisateurs ayant publié du contenu, avec leurs slugs. /?author=1 redirige vers une archive d'auteur qui révèle le slug dans l'URL. Les slugs correspondent souvent à l'identifiant de connexion, ce qui donne à l'attaquant la moitié des identifiants.
Restreindre le point d'accès des utilisateurs pour les visiteurs anonymes et bloquer les scans d'auteurs réduit le bruit de reconnaissance. Les noms d'utilisateur ne sont pourtant pas des secrets. Les masquer ne constitue pas une mesure de sécurité à part entière.
Limiter le débit des requêtes REST anonymes aide contre le scraping et les sondages automatisés. Appliquez-le uniquement au trafic anonyme et testez ensuite. L'éditeur de blocs utilise l'API REST pour les utilisateurs connectés, et les intégrations s'authentifient avec des mots de passe d'application (dans le cœur depuis WordPress 5.6). Une limite qui les touche cassera l'édition ou une tâche de synchronisation, avec des symptômes difficiles à relier à la cause.
Ce que cela ne fait pas : la limitation de débit ne corrige pas un point d'accès REST vulnérable dans un plugin. Elle ne fait que ralentir les tentatives de l'exploiter.
Pourquoi un plugin ne peut pas arrêter une attaque DDoS
Un plugin est du code PHP. Il ne s'exécute qu'une fois la requête passée par le réseau, acceptée par le serveur web et confiée à un worker PHP. Un déluge volumétrique sature votre bande passante, vos limites de connexions ou votre pool de workers PHP bien avant ce stade. Même si le plugin rejette chaque requête en une milliseconde, chaque rejet occupe tout de même un worker, et un serveur n'en a qu'un nombre limité.
Les déluges applicatifs sont différents : de nombreuses requêtes coûteuses mais d'apparence valide, comme des recherches ou des pages non mises en cache. Ici, une limitation de débit plus proche de l'application aide un peu, mais seulement dans la limite de la capacité du serveur.
L'alerte de pic de trafic d'un plugin est utile parce qu'elle vous signale que quelque chose se passe. Elle n'absorbe rien. Tout produit qui présente un plugin WordPress comme une « protection DDoS » en promet trop.
Ce que fait un CDN ou un pare-feu en périphérie, et ce que le serveur web peut ajouter
Un CDN ou un pare-feu en périphérie se place devant votre hébergeur, sur un réseau bien plus vaste que le vôtre. Il peut absorber et filtrer les déluges, appliquer des limites de débit et des règles anti-bots avant que le trafic ne vous atteigne, servir des pages en cache quand votre serveur peine, et soumettre à vérification les requêtes vers wp-login.php et xmlrpc.php. Une fois en place, verrouillez l'origine : n'autorisez que les plages d'IP du CDN sur le pare-feu de votre serveur. Sinon, les attaquants peuvent contourner le CDN et viser directement l'adresse réelle de votre serveur.
Côté serveur web, le [module limit_req](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html) de nginx peut plafonner les tentatives de connexion avant même le démarrage de PHP. Derrière un CDN ou un reverse proxy, configurez d'abord le module real-IP (en ne faisant confiance qu'aux plages de votre proxy) ; sinon $binary_remote_addr correspond à l'adresse du proxy et tous les visiteurs partagent une seule limite :
# contexte http
limit_req_zone $binary_remote_addr zone=wplogin:10m rate=5r/m;
# contexte server
location = /wp-login.php {
limit_req zone=wplogin burst=5 nodelay;
# keep your existing fastcgi_pass / include lines here
}
fail2ban procède autrement. Il lit vos journaux et bannit les récidivistes au niveau du pare-feu, ce qui coûte moins cher que de leur répondre en PHP. Derrière un CDN, cela ne fonctionne pas tel quel : le pare-feu du serveur ne voit que les adresses du CDN, les bannissements doivent donc se faire au niveau du CDN (ou via son API). Sur un hébergement managé, demandez quelle protection réseau votre hébergeur fournit déjà.
Là aussi, il y a des limites. Un pare-feu en périphérie ne corrige ni les mots de passe faibles ni les plugins vulnérables. Il n'aide pas non plus contre ce qu'un attaquant peut faire après s'être connecté, sujet traité dans la désactivation de l'éditeur de fichiers WordPress.
Un ordre de mise en place pour les PME européennes
- Mots de passe forts et uniques et 2FA pour chaque administrateur et éditeur.
- Limitation des connexions avec des seuils par IP et par nom d'utilisateur, détection correcte de l'IP du client et procédure de récupération testée.
- La décision sur XML-RPC : vérifier les journaux, puis utiliser le filtre ou un blocage au niveau du serveur.
- Restrictions sur l'énumération des utilisateurs et limites sur les requêtes REST anonymes.
- Un CDN ou un pare-feu en périphérie avec origine verrouillée pour les sites dont l'indisponibilité coûte de l'argent.
Cela compte aussi pour la conformité. L'article 32, paragraphe 1, point b), du RGPD exige la confidentialité, l'intégrité, la disponibilité et la résilience constantes des systèmes (RGPD sur EUR-Lex). Pour les entités relevant du champ d'application de la directive NIS 2, l'article 21, paragraphe 2, point j), cite l'authentification multifacteur parmi les mesures minimales (directive NIS 2 sur EUR-Lex). Consultez la loi nationale de transposition de NIS 2 de votre pays pour les détails.
Le plugin Security Audit & Compliance de secaudit.eu propose la limitation des connexions, la désactivation de XML-RPC, la limitation de débit des requêtes REST anonymes et des alertes de pic de trafic. Ce n'est pas une protection DDoS ; pour cela, utilisez un CDN ou un pare-feu en périphérie. → secaudit.eu
Prochaine étape : parcourez le reste de la checklist de sécurité WordPress. Si vos journaux montrent déjà des connexions réussies que vous ne reconnaissez pas, passez plutôt aux signes d'un site piraté.
FAQ
Désactiver XML-RPC va-t-il casser Jetpack ou mon application ?
C'est possible. Cherchez dans vos journaux d'éventuels clients XML-RPC légitimes et consultez la documentation actuelle de l'éditeur. Le filtre xmlrpc_enabled est l'option la plus douce, le blocage au niveau du serveur la plus stricte. Testez après l'une comme l'autre.
Renommer wp-login.php arrête-t-il la force brute ?
Cela réduit le bruit des bots simples, mais ce n'est pas une mesure de sécurité. Les attaquants peuvent toujours trouver la page de connexion ou passer par XML-RPC. Utilisez aussi la limitation des connexions et la 2FA.
Mon plugin de sécurité suffit-il pendant une attaque DDoS ?
Non. Contactez votre hébergeur ou votre fournisseur de CDN. Le filtrage en périphérie et la mise en cache sont ce qui maintient le site accessible.
La limitation des connexions peut-elle me bloquer moi-même ?
Oui, si l'IP du client est mal détectée ou si vous vous trompez plusieurs fois de mot de passe. Placez votre IP sur liste d'autorisation et gardez un accès WP-CLI ou SFTP prêt pour désactiver le plugin.
Cet article est une information générale et ne constitue pas un conseil juridique.
Vérifiez votre propre site
Security Audit & Compliance est l’extension WordPress de secaudit.eu : elle recherche les logiciels malveillants, le spam caché, les fichiers du cœur modifiés et le code vulnérable, et rattache ses constats à l’article 32 du RGPD, à l’article 21 de NIS2 et à l’OWASP Top 10.
Voir ce que vérifie l’extension