Comment fonctionne cette vérification
Cette vérification n'agit que si ton site est sous WordPress, ce qu'elle détecte en cherchant wp-content ou wp-includes dans le HTML de la page principale. S'ils n'y sont pas, elle ne fait rien. S'ils y sont, elle teste trois fuites courantes. Première : la balise <meta name="generator" content="WordPress 6.x"> dans le HTML, qui révèle la version exacte (sévérité faible). Deuxième : le fichier /readme.html, que WordPress livre avec chaque installation et qui indique aussi la version (faible). Troisième : la route /wp-json/wp/v2/users de l'API REST ; si elle répond 200 avec du JSON contenant les champs slug et name, elle livre la liste des utilisateurs avec leur identifiant de connexion (sévérité moyenne).
Pourquoi c'est important
WordPress fait tourner plus de 40 % du web, ce qui en fait la cible favorite des attaques automatisées. Ces attaques fonctionnent en deux étapes : identifier la version et les plugins pour choisir un exploit, puis essayer des mots de passe sur la connexion. La version exposée règle la première étape. La liste des utilisateurs règle la moitié de la seconde : avec le slug de chaque utilisateur (qui est son identifiant de connexion, pas son nom affiché), il ne manque à l'attaquant que le mot de passe, et celui de admin, editor ou du nom du propriétaire est testé des milliers de fois par minute. C'est pourquoi l'énumération des utilisateurs est de sévérité moyenne et les deux autres de sévérité faible.
Comment corriger
Version dans la meta generator
Dans le functions.php de ton thème enfant ou dans un petit plugin à toi :
remove_action('wp_head', 'wp_generator');
Note que la version apparaît aussi dans les paramètres ?ver=6.x des CSS et JS du cœur. La masquer complètement demande un plugin de sécurité ; mais ce qui te protège vraiment, c'est de garder WordPress à jour, pas de cacher le numéro.
readme.html
Supprime-le après chaque installation et mise à jour (WordPress le recrée), ou bloque-le côté serveur. En nginx : location = /readme.html { return 404; }. En Apache, dans le .htaccess : <Files readme.html> Require all denied </Files>. Fais de même avec license.txt.
Énumération des utilisateurs
Restreins la route des utilisateurs de l'API REST aux sessions authentifiées. Sans plugin, dans functions.php :
add_filter('rest_endpoints', function ($endpoints) {
if (!is_user_logged_in()) {
unset($endpoints['/wp/v2/users']);
unset($endpoints['/wp/v2/users/(?P<id>[\d]+)']);
}
return $endpoints;
});
Les plugins de sécurité habituels (Wordfence, Solid Security, All-In-One Security) ont une option équivalente. Ferme aussi l'ancienne énumération par ?author=1, qui redirige vers /author/nom/, et ajoute une limite de tentatives et un second facteur à la connexion : même si l'identifiant fuit, le mot de passe seul ne suffit plus.
Vérifie que c'est corrigé
curl -s https://tondomaine.com | grep -io '<meta name="generator"[^>]*>'
curl -s -o /dev/null -w "%{http_code}\n" https://tondomaine.com/readme.html
curl -s -o /dev/null -w "%{http_code}\n" https://tondomaine.com/wp-json/wp/v2/users
Attendu : la première ne renvoie rien ; la deuxième, 404 ou 403 ; la troisième, 401 ou 403 (ou 404 si tu as retiré la route).
Questions fréquentes
Ne suffit-il pas de renommer l'utilisateur « admin » ?
Ça aide contre les attaques les plus bêtes, mais si l'API REST liste les utilisateurs, le nouveau nom se découvre en une requête. Renomme-le et ferme l'énumération.
Mon thème ou un plugin utilise l'API REST des utilisateurs côté public.
C'est rare, mais ça arrive avec certains annuaires d'auteurs. Dans ce cas, au lieu de retirer la route, limite les champs qu'elle renvoie (sans slug) ou restreins-la par capacité d'utilisateur. Teste d'abord sur un environnement de préproduction.
Cette vérification regarde-t-elle les plugins vulnérables ?
Non ; elle regarde les fuites de l'installation de base. Les plugins obsolètes sont en partie détectés par bibliothèques obsolètes. Et si tu as activé WP_DEBUG_LOG, le fichier public qu'il crée est couvert par journaux exposés.