Top 5 des mesures de sécurité à implémenter d'urgence sur votre site WordPress
XML-RPC ouvert, utilisateurs exposés, headers absents… Voici 5 failles actives par défaut sur WordPress, avec le code prêt à copier-coller pour les corriger en moins d'une heure.
WordPress alimente 43% du web. C’est aussi pourquoi c’est la cible numéro un des scripts d’attaque automatisés. Un bot ne “choisit” pas votre site parce qu’il vous en veut, il scanne des plages d’IP entières à la recherche de configurations par défaut, et WordPress en a beaucoup.
Ce qui suit n’est pas une liste de conseils vagues. Ce sont 5 failles actives sur la plupart des sites WordPress non configurés, avec le code pour les fermer.
Avant toute modification : sauvegardez votre site (fichiers + base de données). Ces snippets fonctionnent sur la grande majorité des hébergements, mais chaque configuration est différente.
1. Désactiver XML-RPC
XML-RPC est un protocole des années 2000, actif par défaut sur WordPress. Il permettait à l’époque de se connecter à son blog depuis une application mobile. En 2025, son usage principal est de servir de vecteur pour les attaques par force brute : un seul appel XML-RPC peut tester des milliers de combinaisons identifiant/mot de passe en une requête, sans déclencher les protections classiques de limitation de connexion.
Si vous n’utilisez pas Jetpack ni une app mobile connectée à WordPress, il n’y a aucune raison de laisser ce fichier accessible.
Option 1 — Via .htaccess (bloque avant que PHP soit chargé, plus efficace) :
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
Option 2 — Via functions.php :
add_filter( 'xmlrpc_enabled', '__return_false' );
Option 3 — Bloquer uniquement les méthodes les plus exploitées, sans désactiver complètement :
add_filter( 'xmlrpc_methods', function( $methods ) {
unset( $methods['system.multicall'] );
unset( $methods['system.listMethods'] );
unset( $methods['system.getCapabilities'] );
return $methods;
} );
Vérification : Accédez à https://votre-site.com/xmlrpc.php. Une erreur 403, c’est bon. Si vous voyez “XML-RPC server accepts POST requests only”, le fichier est encore accessible.
2. Bloquer l’énumération des utilisateurs
Par défaut, WordPress expose la liste de vos comptes à n’importe qui. Deux routes accessibles sans authentification :
https://votre-site.com/?author=1— redirige vers le profil de l’utilisateur avec l’ID 1 (souvent l’admin)https://votre-site.com/wp-json/wp/v2/users— retourne un JSON avec les logins, avatars et IDs de tous les comptes
Un attaquant récupère ainsi les identifiants exacts. Il n’a plus qu’à trouver le mot de passe.
Bloquer la redirection ?author= dans functions.php :
add_action( 'init', function() {
if ( ! is_admin() && isset( $_GET['author'] ) ) {
wp_die( 'Accès refusé.', 403 );
}
} );
Supprimer l’endpoint REST /wp/v2/users :
add_filter( 'rest_endpoints', function( $endpoints ) {
if ( isset( $endpoints['/wp/v2/users'] ) ) {
unset( $endpoints['/wp/v2/users'] );
}
if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
}
return $endpoints;
} );
Masquer le login dans les réponses de l’API REST :
add_filter( 'rest_prepare_user', function( $response, $user, $request ) {
$data = $response->get_data();
unset( $data['slug'] );
unset( $data['url'] );
$response->set_data( $data );
return $response;
}, 10, 3 );
Test : Ouvrez un onglet en navigation privée et accédez à votre-site.com/?author=1 puis à votre-site.com/wp-json/wp/v2/users. Si l’un ou l’autre répond encore, le snippet n’est pas actif.
3. Sécuriser les headers HTTP
Les en-têtes HTTP de sécurité sont des instructions que votre serveur envoie au navigateur pour lui dire comment traiter le contenu de la page. WordPress n’en envoie quasiment aucun par défaut.
Sans ces headers, votre site est exposé aux attaques XSS (injection de scripts dans la page), au clickjacking (superposition d’une iframe invisible pour piéger un utilisateur), et à des fuites d’informations sur votre stack technique.
Outil pratique pour tester vos headers actuels : securityheaders.com
Via .htaccess (serveurs Apache) :
<IfModule mod_headers.c>
# Empêche le clickjacking
Header always set X-Frame-Options "SAMEORIGIN"
# Empêche le MIME-sniffing
Header always set X-Content-Type-Options "nosniff"
# Force HTTPS (à activer uniquement si le site est en HTTPS)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Contrôle les informations envoyées au referrer
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Désactive les fonctionnalités navigateur inutiles
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
# Content-Security-Policy (version conservatrice — à adapter selon vos besoins)
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self';"
# Supprime l'en-tête X-Powered-By
Header unset X-Powered-By
Header always unset X-Powered-By
</IfModule>
Via functions.php (si vous n’avez pas accès au .htaccess) :
add_action( 'send_headers', function() {
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'X-Content-Type-Options: nosniff' );
header( 'Referrer-Policy: strict-origin-when-cross-origin' );
header( 'Permissions-Policy: geolocation=(), microphone=(), camera=()' );
header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' );
} );
Le
Content-Security-Policyest le header le plus puissant, et le plus délicat. Une règle trop restrictive peut casser Google Analytics, des polices externes, ou un script de chat. Testez d’abord en modeContent-Security-Policy-Report-Onlyavant de l’activer en production.
4. Restreindre l’API REST WordPress
L’API REST est utile pour les développeurs et les applications headless. Sur un site vitrine ou e-commerce standard, elle expose par défaut des informations qui n’ont rien à faire en accès libre : liste des utilisateurs, types de contenus, et selon les plugins installés, des métadonnées sur la configuration du site.
Restreindre l’API REST aux utilisateurs connectés :
add_filter( 'rest_authentication_errors', function( $result ) {
if ( ! empty( $result ) ) {
return $result;
}
if ( ! is_user_logged_in() ) {
return new WP_Error(
'rest_not_logged_in',
'L\'accès à l\'API REST est restreint.',
array( 'status' => 401 )
);
}
return $result;
} );
Ce snippet bloque tout l’API REST pour les visiteurs non connectés. Si votre site utilise Gutenberg en frontend, WooCommerce, ou un plugin qui s’appuie sur l’API REST côté public, certaines fonctionnalités seront affectées. Dans ce cas, préférez l’approche sélective ci-dessous.
Supprimer uniquement les endpoints sensibles :
add_filter( 'rest_endpoints', function( $endpoints ) {
$endpoints_to_remove = array(
'/wp/v2/users',
'/wp/v2/users/(?P<id>[\d]+)',
'/wp/v2/settings',
'/wp/v2/themes',
'/wp/v2/plugins',
);
foreach ( $endpoints_to_remove as $endpoint ) {
if ( isset( $endpoints[ $endpoint ] ) ) {
unset( $endpoints[ $endpoint ] );
}
}
return $endpoints;
} );
Masquer la version WordPress dans les réponses REST :
add_filter( 'rest_index', function( $response ) {
$data = $response->get_data();
unset( $data['namespaces'] );
unset( $data['authentication'] );
$response->set_data( $data );
return $response;
} );
5. Durcir l’accès au back-office WordPress
L’URL d’administration WordPress (/wp-admin et /wp-login.php) est connue de tous les bots. Des millions de tentatives de connexion par force brute ciblent ces deux URLs chaque jour, sur des sites de toutes tailles, sans distinction. Un blog personnel reçoit exactement les mêmes tentatives qu’un e-commerce à 10 000 commandes par mois.
Limiter l’accès à wp-login.php par adresse IP (si vous avez une IP fixe) :
<Files wp-login.php>
Order Deny,Allow
Deny from all
Allow from 1.2.3.4 # Remplacez par votre adresse IP
</Files>
Désactiver la navigation dans les répertoires :
Options -Indexes
Protéger wp-config.php :
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>
Masquer la version de WordPress dans functions.php :
// Supprimer la version du head et des flux RSS
remove_action( 'wp_head', 'wp_generator' );
add_filter( 'the_generator', '__return_empty_string' );
// Supprimer le paramètre ?ver= des scripts et styles
add_filter( 'style_loader_src', function( $src ) {
return $src ? remove_query_arg( 'ver', $src ) : $src;
} );
add_filter( 'script_loader_src', function( $src ) {
return $src ? remove_query_arg( 'ver', $src ) : $src;
} );
Désactiver l’éditeur de fichiers depuis le back-office, dans wp-config.php :
define( 'DISALLOW_FILE_EDIT', true );
Un accès compromis à un compte admin ne donne plus accès à l’édition directe des fichiers PHP. C’est une ligne. Pas de raison de ne pas l’avoir.
Sur la double authentification (2FA) : c’est probablement la mesure la plus efficace contre les compromissions par credential stuffing. Plugins fiables : WP 2FA ou Google Authenticator. Activez-le au moins sur les comptes administrateurs.
Ces 5 mesures ne font pas un site sécurisé
Elles réduisent la surface d’attaque. C’est utile, mais incomplet.
Un site WordPress véritablement sécurisé, c’est aussi : des mises à jour régulières des plugins et du core, un pare-feu applicatif correctement configuré, un monitoring des fichiers critiques, et des sauvegardes externalisées testées.
La question n’est pas de savoir si votre site sera ciblé. Les bots ne font pas de tri. La question c’est de savoir si quelque chose sera là pour les bloquer quand ils arrivent.
Vous voulez savoir où en est votre site ? Demandez un diagnostic gratuit sur CyberPress — audit complet, réponse humaine sous 24h, sans engagement.