Lors d’un audit rapide sur un site client fin novembre, il nous a suffi de charger trois URL pour savoir que le cœur datait de plusieurs mois, que le thème actif portait un nom précis, et que deux dossiers de wp-content/uploads s’affichaient en listing complet. Aucune de ces informations n’est une faille en soi. Mais chacune raccourcit le travail d’un attaquant qui cherche une extension vulnérable à exploiter sur une version connue.
Ce type de fuite ne nécessite aucune compétence particulière côté attaquant : il s’agit d’aller lire des fichiers ou des en-têtes que WordPress expose par défaut, sans configuration additionnelle. La bonne nouvelle, c’est que fermer ces fuites prend en général moins d’une heure sur un site déjà en production. Voici la checklist que nous suivons systématiquement.
Le fichier readme.html à la racine
Chaque installation de WordPress dépose un fichier readme.html à la racine, qui contient le numéro de version exact du cœur. Ce fichier n’a aucune utilité en production : il documente l’installation pour un humain, pas pour votre serveur. Le supprimer après chaque mise à jour est fastidieux, alors autant en bloquer l’accès une fois pour toutes via une règle serveur.
Sous Apache, dans le .htaccess :
<Files "readme.html">
Require all denied
</Files>
Sous nginx, dans le bloc server :
location = /readme.html {
deny all;
}
La meta generator et les en-têtes qui trahissent la version

WordPress ajoute par défaut une balise <meta name="generator" content="WordPress 6.1.1"> dans le <head> de chaque page publique. Cette balise part directement du numéro de version stocké en base, donc elle est toujours à jour, ce qui la rend particulièrement fiable pour un attaquant qui scanne des milliers de sites à la recherche d’une version précise.
On la retire avec un simple hook dans functions.php ou dans une extension maison :
remove_action( 'wp_head', 'wp_generator' );
La même information se retrouve aussi dans les flux RSS (<generator>) et parfois dans les paramètres de requête ?ver= ajoutés automatiquement aux fichiers CSS et JS enregistrés par le cœur, les thèmes et les extensions. Ces numéros de version par ressource sont en réalité plus révélateurs que la meta generator, car ils permettent d’identifier précisément quelle extension est installée et dans quelle version, même après avoir masqué le générateur global.
Les listings de dossiers activés par défaut sur le serveur
Si le serveur web n’a pas explicitement désactivé l’indexation des répertoires, n’importe quel dossier sans fichier index.php affiche la liste de son contenu à qui tape l’URL. C’est fréquent sur wp-content/uploads, wp-content/plugins ou des dossiers de sauvegarde oubliés là par un prestataire pressé.
- Sous Apache, ajoutez
Options -Indexesdans le.htaccessracine. - Sous nginx, vérifiez qu’aucun bloc ne contient
autoindex on;pour les chemins de votre site. - Placez un fichier
index.phpvide dans les dossiers sensibles si vous ne maîtrisez pas la configuration serveur globale.
Les fichiers de logs et de debug accessibles publiquement
Le piège le plus dangereux de cette liste concerne le fichier debug.log. Quand WP_DEBUG_LOG est activé, WordPress écrit ses erreurs PHP dans wp-content/debug.log, un fichier servi sans protection particulière par la plupart des configurations. Ce journal peut contenir des chemins absolus du serveur, des requêtes SQL complètes, parfois des identifiants de connexion à des API tierces si une extension mal codée logge ses erreurs sans filtrage.
Sur un site en production, la règle est simple : jamais de WP_DEBUG actif, ou alors avec le log redirigé hors de la racine web.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/var/log/wordpress/debug.log' );
define( 'WP_DEBUG_DISPLAY', false );
Depuis WordPress 5.1, la constante WP_DEBUG_LOG accepte un chemin personnalisé plutôt qu’un simple booléen, ce qui évite justement d’exposer ce fichier dans wp-content. Pensez aussi aux logs de votre serveur d’application (PHP-FPM, Apache error_log) qui ne doivent jamais être placés sous la racine documentaire du site.
Les fichiers oubliés par les prestataires
En dehors de ce que WordPress génère lui-même, on retrouve régulièrement des fichiers laissés par erreur : archives .zip de sauvegarde à la racine, fichiers .sql d’export de base, dossiers wp-content/uploads/2022/backup-avant-migration. Un attaquant scanne ces motifs de noms en masse. Une revue rapide avec un outil comme WPScan, ou simplement une recherche de fichiers volumineux à la racine et dans uploads, permet de les repérer avant qu’ils ne soient trouvés autrement.
Sur nos sites clients, nous avons pris l’habitude d’ajouter un script de fin de déploiement qui liste tout fichier non attendu à la racine et dans uploads. Ça a permis de repérer deux exports SQL oubliés en un an, avant qu’ils ne soient indexés par un moteur de recherche.
En résumé
Aucune de ces fuites ne constitue une vulnérabilité exploitable par elle-même. Mais elles forment ensemble une carte d’identité du site qui facilite grandement le travail de reconnaissance d’un attaquant, en particulier les campagnes automatisées qui ciblent des versions précises de plugins connus. Fermer readme.html, retirer la meta generator, couper les listings de dossiers et sortir les logs de la racine web sont quatre actions rapides, sans effet de bord fonctionnel, qui devraient figurer dans le check-up standard de tout site mis en production.