Si votre page d’accueil redirige soudain vers un site de casino, ou si vous voyez des comptes admin que vous n’avez jamais créés, vous n’êtes pas face à un “bug WordPress”. Vous êtes face à une compromission, et chaque minute passée à “cliquer partout” peut aggraver les dégâts.
Prérequis : accès à votre hébergeur (FTP/SFTP ou gestionnaire de fichiers), accès à la base de données (phpMyAdmin ou équivalent), idéalement accès SSH/WP-CLI, et une sauvegarde récente (même si elle est potentiellement contaminée). Tout ce qui suit cible WordPress 6.9.4 (avril 2026) et PHP 8.1+. Ne modifiez jamais le cœur de WordPress (fichiers dans wp-includes / wp-admin) pour “corriger” : on réinstalle proprement.
La menace
Un site WordPress hacké, ce n’est pas seulement “un site qui affiche du spam”. L’attaquant peut :
- Voler des sessions (cookies) et se reconnecter en admin même si vous changez le mot de passe.
- Injecter du SEO spam (pages fantômes, liens cachés) qui ruine votre visibilité et votre réputation.
- Installer une porte dérobée (backdoor) pour revenir après le nettoyage.
- Exfiltrer des données (emails, IP, formulaires, commandes WooCommerce).
- Utiliser votre serveur pour envoyer du spam ou attaquer d’autres sites (et vous faire blacklister).
Ce que je vois le plus souvent en dépannage : ce n’est pas WordPress “le problème”, c’est une combinaison plugin vulnérable + identifiants faibles + absence de mises à jour + permissions trop ouvertes. Et le point qui surprend les débutants : un site peut être compromis sans symptôme visible. Les redirections et défacements sont parfois la dernière étape, pas la première.
Pour situer le risque en termes simples : WordPress est une plateforme très utilisée, donc très ciblée. La majorité des compromissions WordPress proviennent historiquement de vulnérabilités dans des plugins/thèmes ou de mots de passe réutilisés/volés, plus que d’une faille “WordPress core”. La meilleure stratégie reste donc : réduire la surface d’attaque et rendre l’accès admin difficile à détourner.
Sources utiles côté WordPress (bon réflexe : lire les pages officielles quand vous doutez) :
Tableau de diagnostic rapide
| Symptôme | Cause probable | Vérification | Solution |
|---|---|---|---|
| Redirections vers un site tiers | JS injecté, plugin compromis, .htaccess modifié |
Voir le code source, vérifier .htaccess, plugins récents |
Nettoyage fichiers + réinstallation core + purge cache/CDN |
| Nouveaux comptes admin inconnus | Identifiants volés, endpoint admin non protégé | Liste utilisateurs, logs de connexion | Supprimer comptes, forcer reset mots de passe + sessions |
| Pages “spam” indexées sur Google | SEO spam via contenu caché ou routes dynamiques | Google Search Console, recherche site:votredomaine |
Nettoyage DB + suppression pages + demandes de réexamen |
| Alertes “malware” navigateur | Scripts malveillants, iframes | Scanner fichiers, comparer core WordPress | Remplacer fichiers, vérifier uploads, durcir headers |
| Serveur lent / CPU élevé | Crypto-miner, spammer, requêtes anormales | Logs serveur, processus, cron WordPress | Isoler site, nettoyer, changer clés, révoquer accès |
Résumé rapide
- Isolez : mettez le site en maintenance, coupez les accès suspects, sauvegardez une copie pour analyse.
- Révoquez : changez tous les mots de passe (WP, FTP/SFTP, DB, hébergeur) et forcez la déconnexion de toutes les sessions.
- Réinstallez proprement WordPress 6.9.4 (core) et remplacez thème/plugins depuis des sources sûres.
- Nettoyez : cherchez les backdoors (souvent dans
wp-content/uploads,mu-plugins,wp-config.php), puis nettoyez la base. - Durcissez : permissions,
DISALLOW_FILE_EDIT, headers, WAF/CDN, 2FA, mises à jour auto. - Surveillez : logs, intégrité fichiers, alertes, Search Console, scans réguliers.
Code vulnérable — ce qu’il ne faut PAS faire
Un grand classique : un “petit snippet” trouvé sur un forum, collé dans functions.php ou un plugin de snippets, qui ajoute un endpoint AJAX. L’intention est légitime (ex. : “mettre à jour une option depuis le front”), mais l’implémentation ouvre la porte à une prise de contrôle.
Rappel vocabulaire :
- Un hook est un point d’accroche dans WordPress. Il existe des actions (déclenchent du code) et des filtres (modifient une valeur).
- AJAX dans WordPress passe souvent par
admin-ajax.phpet des hookswp_ajax_*(connecté) /wp_ajax_nopriv_*(non connecté). - Un nonce est un jeton anti-CSRF (anti soumission forcée). Ce n’est pas un “mot de passe”, mais une protection essentielle.
Exemple volontairement dangereux
Ce code est vulnérable à plusieurs niveaux : pas de nonce, pas de contrôle de capacité (droits), et pire : il met à jour une option depuis une requête non authentifiée.
<?php
/**
* EXEMPLE VULNÉRABLE — NE PAS UTILISER
* Collé dans functions.php : mauvaise idée + aucune protection.
*/
add_action('wp_ajax_nopriv_bpcab_update_option', 'bpcab_update_option_vulnerable');
add_action('wp_ajax_bpcab_update_option', 'bpcab_update_option_vulnerable');
function bpcab_update_option_vulnerable() {
// ❌ Pas de nonce : vulnérable CSRF
// ❌ Pas de contrôle de droits : n'importe qui peut appeler l'action
// ❌ Entrées non validées : injection de valeurs inattendues
$option_name = $_POST['option_name'] ?? '';
$option_value = $_POST['option_value'] ?? '';
update_option($option_name, $option_value);
wp_send_json_success(array(
'message' => 'Option mise à jour',
));
}
Comment l’attaque fonctionne (sans “recette d’exploit”)
Voici ce qui se passe en coulisses :
- Comme l’action est accessible en
nopriv, un visiteur non connecté peut l’appeler. - Sans nonce, un attaquant peut déclencher l’action depuis un autre site (CSRF) ou directement.
- Sans capability check (contrôle de droits), WordPress ne bloque pas l’opération.
- Selon l’option modifiée, l’attaquant peut casser le site, injecter des réglages, ou préparer une étape suivante (ex. : activer l’inscription + rôle admin via un autre bug, modifier des URLs, etc.).
J’ai souvent vu des variantes encore plus graves : écriture de fichiers via file_put_contents(), exécution de commandes système, ou “import” de contenu sans validation. La plupart du temps, le snippet a été copié au mauvais endroit, mal compris, et laissé en production sans audit.
Code sécurisé — la bonne implémentation
On reprend la même idée (mettre à jour un réglage), mais on le fait comme un code WordPress 6.9.4+ propre : capabilities, nonce, validation stricte, et pas de nopriv si ce n’est pas indispensable.
Où coller ce code ? Le plus sûr : un petit plugin custom (recommandé) ou un mu-plugin (plugin “must-use”). Évitez functions.php si vous débutez : une erreur de syntaxe (point-virgule oublié) peut mettre le site en écran blanc.
Option A (recommandée) : mu-plugin
Créez le fichier : wp-content/mu-plugins/bpcab-security-safe-ajax.php (créez le dossier s’il n’existe pas). Les mu-plugins sont chargés automatiquement.
<?php
/**
* Plugin Name: BPCAB - AJAX sécurisé (exemple)
* Description: Exemple pédagogique : mise à jour d'une option via AJAX de façon sécurisée.
* Version: 1.0.0
* Requires at least: 6.9
* Requires PHP: 8.1
*/
if ( ! defined('ABSPATH') ) {
exit; // Sécurité : empêche l'accès direct au fichier
}
add_action('wp_ajax_bpcab_update_site_setting', 'bpcab_update_site_setting_secure');
function bpcab_update_site_setting_secure() {
// 1) Vérifie le nonce (anti-CSRF)
// Le champ attendu côté JS : security: '...'
check_ajax_referer('bpcab_site_setting', 'security');
// 2) Vérifie les droits : ici, seuls les admins (capacité "manage_options")
if ( ! current_user_can('manage_options') ) {
wp_send_json_error(array(
'message' => 'Droits insuffisants.',
), 403);
}
// 3) Whitelist stricte : on n'autorise que certaines options
$allowed_options = array(
'bpcab_banner_text',
);
$option_name = isset($_POST['option_name']) ? sanitize_key(wp_unslash($_POST['option_name'])) : '';
if ( ! in_array($option_name, $allowed_options, true) ) {
wp_send_json_error(array(
'message' => 'Option non autorisée.',
), 400);
}
// 4) Validation / sanitation de la valeur
$option_value = isset($_POST['option_value']) ? wp_unslash($_POST['option_value']) : '';
$option_value = sanitize_text_field($option_value);
update_option($option_name, $option_value, true);
wp_send_json_success(array(
'message' => 'Option mise à jour en toute sécurité.',
));
}
Pourquoi c’est plus sûr (explication simple puis technique)
Simple : vous exigez que la requête provienne d’un admin connecté et qu’elle contienne un jeton valide. Vous limitez aussi ce qui peut être modifié. Résultat : même si quelqu’un “voit” l’URL AJAX, il ne peut pas s’en servir.
Technique :
check_ajax_referer()bloque les requêtes sans nonce valide. Référence : developer.wordpress.org.current_user_can('manage_options')impose une capacité WordPress. Référence : developer.wordpress.org.sanitize_key(),sanitize_text_field()etwp_unslash()évitent une partie des entrées inattendues. Référence : Sanitizing Data.- La whitelist empêche de transformer votre endpoint en “update_option universel”. C’est un détail, mais c’est souvent là que la sécurité se joue.
Note page builders (Divi 5, Elementor, Avada)
Divi, Elementor et Avada n’empêchent pas ce type de vulnérabilité : le risque vient du code PHP qui traite la requête. Si vous ajoutez des formulaires via un builder, gardez ce réflexe :
- côté front : nonce + requête authentifiée si action sensible ;
- côté serveur : droits + whitelist + sanitation + validation ;
- ne jamais exposer d’actions “admin” en
nopriv.
Configuration serveur
La configuration serveur ne “nettoie” pas un hack, mais elle réduit fortement les récidives. Je vous donne ici du copier-coller prudent. Testez d’abord en staging si possible.
wp-config.php : durcissement minimal utile
Éditez wp-config.php (à la racine). Faites une sauvegarde du fichier avant. Ajoutez ou vérifiez :
<?php
// Empêche l'édition de fichiers via l'admin (cible fréquente après compromission)
define('DISALLOW_FILE_EDIT', true);
// Optionnel : empêche aussi l'installation/mise à jour via l'admin (à activer si vous gérez via Git/CI)
define('DISALLOW_FILE_MODS', false);
// Force SSL sur l'admin si votre site est en HTTPS (recommandé)
define('FORCE_SSL_ADMIN', true);
// Limite la fenêtre d'autosave/ révisions (pas sécurité pure, mais réduit bruit en DB)
define('WP_POST_REVISIONS', 20);
Point d’attention : si vous êtes derrière un proxy/CDN, FORCE_SSL_ADMIN peut provoquer des boucles si l’hébergeur ne transmet pas correctement X-Forwarded-Proto. Dans ce cas, corrigez la config proxy côté serveur plutôt que de désactiver le SSL.
.htaccess (Apache) : bloquer l’exécution de PHP dans uploads
Beaucoup de malwares WordPress se cachent dans wp-content/uploads. Sur un site normal, vous n’avez aucune raison d’exécuter du PHP dans ce dossier.
Créez (ou éditez) wp-content/uploads/.htaccess :
# Bloque l'exécution de PHP dans uploads (Apache)
<FilesMatch ".php$">
Require all denied
</FilesMatch>
Si votre hébergeur est en Nginx, l’équivalent se fait dans la conf serveur (demandez au support). Ne tentez pas d’inventer une directive Nginx dans un fichier WordPress : ça ne marchera pas.
Headers HTTP : réduire l’impact XSS / clickjacking
Si vous pouvez configurer des headers (via l’hébergeur, un plugin de sécurité, ou votre vhost), ces trois-là sont un bon départ :
# Exemples de headers (à adapter à votre serveur/CDN)
Content-Security-Policy: frame-ancestors 'self';
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Une vraie CSP complète est plus complexe (surtout avec des builders qui injectent du inline JS/CSS). Commencez par frame-ancestors pour limiter le clickjacking, c’est généralement peu destructif.
Permissions fichiers : le minimum réaliste
- Dossiers : 755
- Fichiers : 644
wp-config.php: souvent 640 ou 600 selon l’hébergement
Évitez le réflexe “je mets tout en 777 pour que ça marche”. J’ai vu des sites “réparés” comme ça… puis rehackés dans l’heure.
Vérifier si votre site est vulnérable
Objectif : trouver où l’attaquant est entré, et si une porte dérobée reste. Sans ça, vous nettoyez pour rien.
Avec WP-CLI : inventaire et signaux faibles
WP-CLI est l’outil en ligne de commande le plus utile pour diagnostiquer vite. Référence : WP-CLI commands.
# Version WordPress (vérifiez que vous êtes bien en 6.9.4+)
wp core version
# Liste des plugins + statut
wp plugin list
# Liste des thèmes
wp theme list
# Liste des utilisateurs admins
wp user list --role=administrator --fields=ID,user_login,user_email,registered
# Vérifie l'intégrité des fichiers core (détecte les fichiers modifiés)
wp core verify-checksums
Interprétation :
- Si
wp core verify-checksumsremonte des fichiers modifiés : considérez le core compromis. On réinstalle. - Si vous voyez des admins inconnus : supprimez-les après avoir sécurisé l’accès (sinon ils reviennent).
Recherche de fichiers suspects (sans casser le site)
Sur un serveur Linux, ces commandes sont utiles. Elles ne sont pas “magiques”, mais elles font gagner du temps.
# Cherche du PHP dans uploads (souvent anormal)
find wp-content/uploads -type f -name "*.php" -print
# Cherche des fonctions typiques d'obfuscation (signal, pas preuve)
grep -R --line-number "base64_decode|gzinflate|str_rot13|eval(" wp-content | head -n 50
Ne supprimez pas “tout ce qui contient base64_decode” à l’aveugle : certains plugins légitimes peuvent l’utiliser. Ce que vous cherchez, c’est le combo : fichier au mauvais endroit + code illisible + dates récentes + nom bizarre.
Vérifier les logs : le passage obligé
- Access logs : pics de requêtes sur
/wp-login.php,/xmlrpc.php(si activé),/wp-json/,/admin-ajax.php. - Error logs : erreurs PHP répétées (souvent causées par un malware mal codé), warnings dans des fichiers inconnus.
- Logs WAF/CDN (Cloudflare, etc.) : blocages, IPs, pays, patterns.
Ce que je cherche en premier : une séquence “upload d’un fichier” suivi d’un appel direct à ce fichier, ou une rafale sur un endpoint précis d’un plugin.
Requêtes SQL de diagnostic (à utiliser avec prudence)
Si vous avez accès à phpMyAdmin, vous pouvez lister des éléments suspects. Adaptez le préfixe wp_ si le vôtre est différent.
-- Utilisateurs admins
SELECT u.ID, u.user_login, u.user_email
FROM wp_users u
JOIN wp_usermeta m ON m.user_id = u.ID
WHERE m.meta_key = 'wp_capabilities'
AND m.meta_value LIKE '%administrator%';
-- Options chargées automatiquement (autoloader) : cible fréquente d'injection
SELECT option_name, LENGTH(option_value) AS len
FROM wp_options
WHERE autoload = 'yes'
ORDER BY len DESC
LIMIT 30;
Si vous voyez une option avec une valeur énorme et illisible (souvent du code), c’est un drapeau rouge. Là encore : signal, pas verdict.
Erreurs de sécurité fréquentes
| Erreur | Risque | Solution |
|---|---|---|
| Nettoyer “à la main” en supprimant 2-3 fichiers au hasard | Backdoor restante, rehack rapide | Réinstallation core + remplacement plugins/thèmes + audit uploads + DB |
Copier un snippet dans functions.php sans comprendre |
RCE/CSRF/élévation de privilèges | Plugin custom + nonce + capabilities + validation stricte |
| Oublier de vider le cache (plugin, serveur, CDN) | Vous croyez que le hack persiste, ou vous ne voyez pas le retour à la normale | Purger tous les caches après nettoyage |
| Tester directement en production sans sauvegarde | Perte de données, indisponibilité | Clone/staging, snapshot, plan de rollback |
| Utiliser un hook inadapté (action vs filtre), mauvaise priorité | Contrôles de sécurité non exécutés | Vérifier le hook, la priorité, et tester avec logs |
| Oublier les nonces sur formulaires/AJAX | CSRF (actions admin déclenchées à votre insu) | wp_nonce_field() / check_admin_referer() / check_ajax_referer() |
| Permissions trop ouvertes (777), FTP partagé | Écriture de malware, modification silencieuse | 644/755, comptes séparés, SFTP, clés SSH |
| Version PHP trop ancienne | Compatibilité faible, surface d’attaque plus large | PHP 8.1+ (idéalement plus récent si votre hébergeur le propose) |
| Suivre un vieux tutoriel (pré-6.x) sans adapter | Code cassé, fausses protections | Références developer.wordpress.org + tests sur WP 6.9.4 |
| Permaliens non régénérés après restauration | 404, comportements bizarres, fausses alertes | Réglages > Permaliens > Enregistrer |
Checklist de durcissement
- Mises à jour : WordPress, plugins, thèmes à jour (supprimez ce qui est inactif).
- Comptes : aucun admin “de secours” oublié, mots de passe uniques, 2FA si possible.
- Sessions : forcer la déconnexion globale après incident.
- Fichiers : pas de PHP dans
uploads, pas de fichiers inconnus dansmu-plugins. - wp-config.php :
DISALLOW_FILE_EDITactivé, clés de sécurité régénérées. - Permissions : 644/755, pas de 777.
- Accès serveur : SFTP/SSH, pas de FTP en clair, comptes séparés.
- Protection login : limitation de tentatives, CAPTCHA si adapté, WAF/CDN.
- Backups : sauvegardes automatiques + test de restauration (sinon ça ne compte pas).
- Monitoring : alertes sur création d’admin, modification fichiers, uptime.
Que faire si le site est déjà compromis ?
On passe en mode incident. Le piège courant : commencer par “supprimer le malware” sans d’abord couper l’accès. Dans mon expérience, c’est comme éponger une fuite sans fermer le robinet.
Étape 1 — Isoler sans détruire les preuves
- Activez une page de maintenance (via l’hébergeur, ou un plugin fiable). Évitez de laisser le site servir du malware aux visiteurs.
- Faites une copie des fichiers et de la base (zip + export SQL). Stockez-la hors serveur. Cette copie sert à analyser l’entrée et à prouver ce qui s’est passé.
- Notez l’heure et les symptômes (redirection, comptes, fichiers modifiés). Ça aide à corréler avec les logs.
Étape 2 — Révoquer tous les accès (pas seulement WordPress)
- Changez le mot de passe de l’hébergeur (panel), puis activez 2FA si disponible.
- Changez les mots de passe SFTP/SSH (ou régénérez les clés SSH). Supprimez les comptes inutiles.
- Changez le mot de passe de la base de données et mettez à jour
wp-config.php. - Changez tous les mots de passe WordPress (admins en priorité).
Ensuite seulement, forcez la déconnexion globale des sessions WordPress. Le plus simple côté admin : réinitialiser les mots de passe. Si vous avez WP-CLI :
# Exemple : force un nouveau mot de passe (à faire pour chaque admin)
wp user update VOTRE_ID --user_pass="$(wp eval 'echo wp_generate_password(32, true, true);')"
Vous pouvez aussi régénérer les clés de sécurité dans wp-config.php, ce qui invalide les cookies de session. Utilisez le service officiel WordPress pour générer les nouvelles clés : WordPress.org secret-key salts.
Étape 3 — Identifier le point d’entrée (plugin, thème, identifiants)
Avant de remettre en ligne, cherchez la cause probable :
- plugin/thème récemment installé ou mis à jour ;
- plugin “nulled” (piraté) : c’est une cause massive de compromission ;
- compte admin avec mot de passe réutilisé ;
- accès FTP partagé avec une agence/prestataire ;
- serveur mutualisé avec permissions trop ouvertes.
Si vous n’arrivez pas à déterminer l’entrée, partez du principe qu’elle peut se reproduire et durcissez plus fort (WAF + 2FA + restriction d’accès admin).
Étape 4 — Réinstaller WordPress core proprement (WordPress 6.9.4)
- Téléchargez WordPress depuis la source officielle : wordpress.org/download.
- Remplacez entièrement
wp-adminetwp-includespar des dossiers propres. - Remplacez aussi les fichiers PHP à la racine (
index.php,wp-login.php, etc.) par des versions propres. - Ne remplacez pas
wp-config.phpetwp-contentpour l’instant (c’est là que se cache souvent l’infection).
Avec WP-CLI (si disponible), c’est encore plus propre :
# Réinstalle les fichiers core (sans toucher wp-content)
wp core download --force
Étape 5 — Nettoyer wp-content (thèmes, plugins, uploads)
La stratégie la plus fiable : remplacer plutôt que “nettoyer” plugin par plugin.
- Plugins : supprimez tous les plugins, puis réinstallez-les depuis wordpress.org/plugins ou les sources éditeur. Oui, c’est long. Oui, c’est ce qui marche.
- Thème : idem. Si vous utilisez Divi 5, Elementor, Avada : retéléchargez depuis votre compte officiel (Elegant Themes / Elementor / ThemeFusion). Évitez les ZIP partagés.
- Uploads : cherchez les fichiers PHP, les fichiers récemment modifiés, et les noms anormaux. Appliquez le blocage PHP dans uploads (section serveur).
Piège fréquent : supprimer un plugin compromis mais laisser un mu-plugin malveillant. Vérifiez wp-content/mu-plugins et wp-content/plugins pour tout fichier que vous n’avez pas installé.
Étape 6 — Nettoyer la base de données (sans tout casser)
Je procède en deux passes :
- Pass 1 : comptes utilisateurs, options, contenus visibles (articles/pages).
- Pass 2 : injections discrètes (options autoload, widgets, shortcodes, HTML caché).
Contrôles concrets :
- supprimez les admins inconnus ;
- vérifiez les emails admin ;
- inspectez
wp_options(valeurs énormes, scripts) ; - vérifiez les widgets et menus (injection de liens).
Ne lancez pas de “requête SQL de suppression massive” trouvée sur un forum. J’ai déjà récupéré des sites où quelqu’un a supprimé des options critiques et cassé l’éditeur, les permaliens et WooCommerce.
Étape 7 — Scanner, puis remettre en ligne progressivement
- Activez un plugin de sécurité réputé (scanner + firewall applicatif) si votre budget/stack le permet.
- Remettez le site en ligne avec monitoring (logs + alertes).
- Surveillez pendant 48–72h : créations d’utilisateurs, modifications fichiers, nouvelles redirections.
Étape 8 — Purger caches et CDN (sinon vous allez croire que c’est encore hacké)
- Purge cache plugin (si vous utilisez un cache).
- Purge cache serveur (si l’hébergeur en a un).
- Purge CDN (Cloudflare, etc.).
- Videz aussi le cache navigateur pour vérifier.
Étape 9 — Post-incident : SEO et réputation
- Google Search Console : vérifiez “Problèmes de sécurité” et l’indexation.
- Si du spam a été indexé : supprimez les pages, renvoyez 404/410, demandez réexamen si nécessaire.
- Si vous avez une liste email : prévenez si des données ont pu fuiter (selon votre contexte légal).
Conseils de maintenance et compatibilité
Une fois le site nettoyé, le vrai travail commence : éviter la rechute. Les hacks “qui reviennent” viennent presque toujours d’un de ces points : plugin vulnérable non mis à jour, mot de passe réutilisé, backdoor oubliée, ou accès serveur compromis.
Règles simples qui tiennent dans le temps
- Supprimez les plugins/thèmes inutilisés (désactiver ne suffit pas).
- Limitez les admins : un admin = pouvoir total.
- 2FA sur les comptes admin, surtout si vous utilisez Elementor/Divi/Avada avec des accès partagés.
- Staging : testez les mises à jour importantes hors production.
- Backups testés : une sauvegarde non testée est une hypothèse.
Compatibilité builders (Divi 5, Elementor, Avada) : points d’attention sécurité
- Templates importés : n’importez pas de “packs” venant de sources inconnues. Même si ce n’est pas du PHP, ça peut injecter du JS ou des liens spam.
- Widgets/formulaires : tout ce qui envoie des données doit avoir nonce + validation côté serveur.
- Performance : un site lent masque parfois une compromission (cron abusif, injections). Surveillez les temps de réponse.
Un mot sur PHP 8.1+
Restez sur une version PHP supportée par votre hébergeur (8.1 minimum recommandé ici). Référence : PHP Supported Versions. Une version trop ancienne vous prive de correctifs et complique la compatibilité des plugins modernes.
Ressources
- Hardening WordPress (WordPress.org)
- Security APIs (developer.wordpress.org)
- check_ajax_referer() (référence)
- current_user_can() (référence)
- Générateur officiel de clés SALT (WordPress.org)
- wordpress-develop (GitHub officiel)
- WordPress Core Trac (suivi des tickets)
- WP-CLI Commands (developer.wordpress.org)
- PHP Security (php.net)
FAQ
Dois-je restaurer une sauvegarde ?
Oui, si vous avez une sauvegarde antérieure à la compromission. Sinon, vous risquez de restaurer le malware. Dans le doute, restaurez en staging, scannez, comparez les dates de modification, puis décidez.
Changer le mot de passe WordPress suffit-il ?
Non. Si l’accès serveur (SFTP/SSH) ou l’hébergeur est compromis, l’attaquant peut réinjecter des fichiers. Et si vos clés SALT n’ont pas changé, des sessions peuvent rester valides.
Pourquoi réinstaller WordPress core au lieu de “nettoyer” ?
Parce que c’est plus rapide et plus fiable. Remplacer wp-admin et wp-includes par des versions propres élimine une grande classe d’infections.
Mon site est sous Divi/Elementor/Avada : est-ce plus vulnérable ?
Pas automatiquement. Le risque vient surtout des extensions additionnelles, des templates importés, et des accès admin partagés. Les builders augmentent la surface fonctionnelle, donc vous devez être plus strict sur les mises à jour et les comptes.
Que faire si je ne peux pas accéder à l’admin WordPress ?
Travaillez depuis l’hébergeur : renommez temporairement wp-content/plugins pour désactiver tous les plugins, puis reconnectez-vous. Si ça ne suffit pas, réinstallez le core via WP-CLI ou remplacement des dossiers.
Dois-je supprimer xmlrpc.php ?
Ne supprimez pas des fichiers core. Si vous n’utilisez pas XML-RPC, vous pouvez le bloquer côté serveur/WAF. Certains services (apps, Jetpack, pingbacks) peuvent en dépendre.
Comment savoir si des données ont été volées ?
Vous ne pouvez pas en être certain sans analyse poussée (logs, forensic). Indices : nouveaux admins, scripts inconnus, connexions anormales, exports de DB, requêtes suspectes. Si vous gérez des comptes clients/commandes, traitez l’incident comme potentiellement exfiltrant.
Un plugin de sécurité suffit-il ?
Non. Un bon plugin aide (scan, alertes, durcissement), mais il ne remplace pas : mises à jour, mots de passe uniques, permissions correctes, et hygiène serveur.
J’ai collé un code trouvé en ligne et mon site affiche une erreur critique
Très courant : parenthèse manquante, point-virgule oublié, ou fonction appelée trop tôt (hook incorrect). Désactivez le plugin de snippets via FTP (ou restaurez le fichier), puis réessayez dans un mu-plugin avec une validation stricte. Ne testez pas directement en production sans sauvegarde.
Pourquoi je vois encore des redirections après nettoyage ?
Souvent à cause du cache (plugin/CDN/navigateur) ou d’un script injecté dans la base (widget, option autoload). Purgez tous les caches, puis inspectez le HTML servi et les options longues dans wp_options.
Quelle est la meilleure prévention “simple” ?
Si vous ne faites qu’une chose : supprimez les plugins inutiles et activez 2FA sur les admins. La plupart des incidents que je traite auraient été évités avec ces deux mesures, plus des mises à jour régulières.