2026年11月12日
2026年11月12日
Masquer la version de WordPress : generator, ver=, readme.html
Cet article est une édition localisée de l'original japonais. Lire l'original en japonais
Par défaut, WordPress écrit son numéro de version dans le HTML des pages et dans les flux. Un attaquant peut s'en servir pour chercher si la version présente des vulnérabilités connues. Cet article décrit les endroits où la version s'affiche et la façon de la masquer. Son contenu date d'octobre 2026.
Il faut d'abord savoir que masquer la version n'est qu'une mesure complémentaire. On peut aussi deviner la version d'après le contenu des fichiers CSS et JavaScript, entre autres : la masquer n'empêche donc pas forcément l'identification. Le plus efficace reste de maintenir à jour le cœur de WordPress, les extensions et les thèmes.
Où la version s’affiche
| Emplacement | Contenu affiché | Solution |
|---|---|---|
<head> du HTML |
Une balise comme <meta name="generator" content="WordPress 6.9.4"> |
Filtre the_generator |
| Flux RSS et Atom | Une ligne comme <generator>https://wordpress.org/?v=6.9.4</generator> |
Là aussi, filtre the_generator |
| URL des CSS et JavaScript | Un ?ver= comme style.min.css?ver=6.9.4 |
Filtres style_loader_src et script_loader_src |
| En-têtes HTTP | X-Powered-By: PHP/8.3.x (version de PHP, et non de WordPress) |
expose_php dans php.ini |
readme.html |
Le fait que WordPress est utilisé (le readme.html actuel n'indique pas de numéro de version) | Refuser l'accès |
Les informations du site renvoyées par /wp-json/ de l'API REST (nom, description, URL, fuseau horaire, espaces de noms, etc.) ne contiennent pas la version de WordPress. Il n'est pas nécessaire de réduire la sortie de l'API REST dans le but de masquer la version.
Étape 1 : vérifier ce qui est affiché actuellement
Remplacez l'URL par celle de votre site et exécutez ces commandes sur votre ordinateur ou sur le serveur. Si vous utilisez une extension de cache ou un CDN, videz le cache après vos modifications avant de vérifier.
# Balise generator du HTML
curl -s https://example.com/ | grep -i 'name="generator"'
# generator du flux
curl -s https://example.com/feed/ | grep -i '<generator>'
# Liste des valeurs de ver= attachées aux CSS et JS
curl -s https://example.com/ | grep -oE 'ver=[0-9][0-9.]*' | sort | uniq -c
# En-tête HTTP X-Powered-By
curl -sI https://example.com/ | grep -i 'x-powered-by'
# readme.html est-il lisible ? (200 : lisible)
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html
Si la liste des ver= contient la même valeur que la version de WordPress affichée dans « Tableau de bord » → « Mises à jour » (Dashboard → Updates) de l'administration, la version de WordPress peut être déduite de ces CSS ou JS. Quand le cœur de WordPress ou le thème charge un CSS ou un JS sans préciser de version, la version de WordPress est placée dans ver=.
Étape 2 : choisir où placer le code
Placez le code de cet article à l'un des deux endroits suivants.
- mu-plugin (recommandé) : un fichier PHP placé dans le dossier
wp-content/mu-plugins/(à créer s'il n'existe pas) est chargé sans aucune opération d'activation. L'effet persiste même si vous changez de thème - functions.php du thème enfant : si vous l'écrivez dans le functions.php du thème parent, il sera effacé par une mise à jour du thème
Avec un mu-plugin, regroupez le code de l'étape suivante dans un seul fichier, nommé par exemple wp-content/mu-plugins/hide-wp-version.php.
Étape 3 : masquer la version dans la balise generator et dans ver=
<?php
/**
* Plugin Name: Hide WordPress Version
* Description: Masque la version de WordPress affichée par la balise generator et par le ver= des CSS et JS.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Vide le <meta name="generator"> du HTML et le <generator> des flux.
add_filter( 'the_generator', '__return_empty_string' );
/**
* Remplace le ver= des CSS et JS par une autre valeur, uniquement lorsqu'il est identique à la version de WordPress.
* Comme ver= est remplacé et non supprimé, le cache du navigateur est actualisé après une mise à jour de WordPress.
*/
function wpdr_replace_wp_version_query( $src ) {
if ( ! is_string( $src ) || '' === $src ) {
return $src;
}
$query = wp_parse_url( $src, PHP_URL_QUERY );
if ( empty( $query ) ) {
return $src;
}
parse_str( $query, $args );
$wp_version = get_bloginfo( 'version' );
if ( isset( $args['ver'] ) && $args['ver'] === $wp_version ) {
$src = add_query_arg( 'ver', substr( wp_hash( $wp_version ), 0, 10 ), $src );
}
return $src;
}
add_filter( 'style_loader_src', 'wpdr_replace_wp_version_query', 20 );
add_filter( 'script_loader_src', 'wpdr_replace_wp_version_query', 20 );
Les points à retenir sont les suivants.
- Le filtre
the_generatoragit à la fois sur la balise generator du HTML et sur le generator des flux.remove_action( 'wp_head', 'wp_generator' );ne supprime que la balise du HTML et n'agit donc pas sur les flux - Si vous supprimez tous les
?ver=, le navigateur peut continuer à utiliser d'anciens CSS et JS après une mise à jour d'extension ou de thème. Le code ci-dessus remplace par une autre chaîne, calculée à partir de la version, uniquement les valeurs identiques à la version de WordPress. Comme la valeur change quand vous mettez WordPress à jour, le cache est actualisé - Les
ver=auxquels une extension ou un thème a attribué son propre numéro de version ne sont pas modifiés
Après l'enregistrement, vérifiez avec les commandes de l'étape 1 que generator n'apparaît plus et que la liste des ver= ne contient plus la version de WordPress. Si vous utilisez une extension de cache, videz-le avant de vérifier.
Étape 4 : supprimer l’en-tête X-Powered-By
X-Powered-By est un en-tête ajouté par PHP et non par WordPress ; il indique la version de PHP. Pour le supprimer, mettez expose_php sur Off dans le fichier de configuration de PHP (php.ini). Ce réglage ne peut être modifié que dans php.ini.
expose_php = Off
Voici un exemple pour un VPS Ubuntu avec PHP-FPM (adaptez 8.3 à la version de PHP que vous utilisez).
# Vérifier le réglage actuel
grep -n '^expose_php' /etc/php/8.3/fpm/php.ini
# Après modification, redémarrer PHP-FPM
sudo systemctl restart php8.3-fpm
Le php.ini des paquets Ubuntu a expose_php = Off par défaut. Si l'en-tête apparaît, vérifiez qu'un autre php.ini n'est pas utilisé. Sur un hébergement mutualisé, il est parfois possible de le modifier dans les réglages PHP de l'administration, et parfois non.
Si vous ne pouvez pas modifier php.ini, il est aussi possible de retirer l'en-tête depuis le code de WordPress. Cependant, send_headers est un hook exécuté quand WordPress génère les pages publiques : il n'agit pas sur l'administration ni sur la page de connexion.
add_action( 'send_headers', function () {
header_remove( 'X-Powered-By' );
} );
Étape 5 : refuser l’accès à readme.html et license.txt
readme.html et license.txt sont des fichiers du cœur de WordPress. Le readme.html actuel n'indique pas de numéro de version, mais il révèle que WordPress est utilisé.
Même si vous les supprimez, ils reviennent à la mise à jour du cœur de WordPress. Plutôt que de les supprimer, il est moins fastidieux de refuser l'accès côté serveur web.
Avec Apache (.htaccess)
Ajoutez-le au .htaccess situé dans le dossier de WordPress. Ce qui se trouve entre # BEGIN WordPress et # END WordPress est réécrit par WordPress : écrivez donc en dehors de ce bloc. Il s'agit de la syntaxe d'Apache 2.4 (Order et Deny from all sont l'ancienne syntaxe d'Apache 2.2).
<FilesMatch "^(readme\.html|license\.txt)$">
Require all denied
</FilesMatch>
Avec Nginx
Ajoutez-le dans le bloc server du site, puis vérifiez la configuration avant de la recharger.
location ~* ^/(readme\.html|license\.txt)$ {
deny all;
}
sudo nginx -t && sudo systemctl reload nginx
Après l'ajout, exécutez curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html et vérifiez que vous obtenez un 403.
Ce que masquer ne permet pas d’empêcher
- Le contenu des fichiers CSS et JS de WordPress diffère légèrement d'une version à l'autre : en récupérant les fichiers et en les comparant, on peut deviner la version
- Le
readme.txtou lever=des extensions et des thèmes peut révéler la version de l'extension. Ce sont plutôt les failles des extensions que celles du cœur qui sont visées - Les personnes qui peuvent se connecter à l'administration voient toujours la version comme avant
C'est pourquoi, en plus de masquer la version, mettez à jour le cœur, les extensions et les thèmes, supprimez les extensions inutilisées et désactivez l'édition de fichiers dans l'administration.
Résumé
- La version s'affiche principalement dans generator (HTML et flux) et dans le
?ver=des CSS et JS. Le/wp-json/de l'API REST ne contient pas la version de WordPress add_filter( 'the_generator', '__return_empty_string' );supprime à la fois le generator du HTML et celui des flux- Ne supprimez pas
?ver=: remplacez seulement les valeurs identiques à la version de WordPress, pour ne pas bloquer l'actualisation du cache - Supprimez
X-Powered-Byavecexpose_php = Offdans php.ini readme.htmlrevient après une mise à jour même si on le supprime : refusez donc l'accès côté serveur web- Masquer est une mesure complémentaire ; l'essentiel est de continuer à mettre à jour
Articles associés :
- Configurer les en-têtes de sécurité de WordPress : .htaccess, Nginx et functions.php
- Comment restreindre l'accès à l'API REST de WordPress
- Désactiver l'éditeur de fichiers des thèmes et extensions de WordPress : DISALLOW_FILE_EDIT
Une question sur WordPress ? L'éditeur de ce site est basé au Japon et répond en japonais. Contact (en japonais)