Un site WordPress infecté, ce n’est pas seulement une question de pages qui affichent mal. Quand l’attaque est réelle, elle touche parfois la base de données, la chaîne d’upload, les thèmes et plugins, et plus rarement mais plus gravement le niveau serveur. On le voit surtout quand le “symptôme” disparaît et que le site revient à une autre date, ou quand un nettoyage incomplet laisse une porte arrière silencieuse.
Dans la pratique, une désinfection WordPress réussie, ce n’est pas un outil miracle. C’est une reprise structurée, avec des décisions assumées, des contrôles qui prouvent que la compromission est finie, et une validation finale faite pour résister à l’examen du temps. Le plan ci-dessous est celui que j’utilise comme trame quand je dois reprendre un site avec une urgence d’exploitation, sans transformer la restauration en roulette russe.
Partir des faits, pas de l’affichage
Le premier piège, c’est de se focaliser sur ce que Google, un visiteur, ou une page “hackée” montre à l’écran. Un site peut afficher du contenu injecté via un thème modifié, mais il peut aussi être compromis ailleurs. Avant de toucher aux fichiers, on gagne énormément en fiabilité en répondant à trois questions en parallèle :
1) Depuis quand ?
2) Qu’est-ce qui a changé dans le code ou la base pendant la période de risque ? 3) Quelle est la nature probable de l’intrusion, même sans certitude totale ?Sur un site compromis, les indices concrets sont souvent accessibles. Les journaux d’erreurs du serveur et l’accès HTTP donnent une chronologie utile. Côté WordPress, on peut aussi relever des traces comme des comptes administrateurs créés, des modifications de tables, des options anormales, ou des scripts ajoutés qui n’appartiennent pas à la stack attendue.
J’ai déjà vu des cas où un site semblait uniquement “défiguré” (HTML injecté dans quelques pages), mais la vraie anomalie se cachait dans une modification de fonctions dans un fichier utilitaire, qui redirigeait vers une charge externe selon la géolocalisation et l’agent navigateur. Tant que le test de désinfection ne vérifiait pas ces conditions, la réinfection “réussissait” à revenir, même après restauration partielle.
Isoler le périmètre avant d’effacer
Désinfecter, c’est aussi réduire l’impact. Dès qu’on suspecte une compromission, l’objectif est d’éviter que de nouvelles charges soient servies au public et d’empêcher l’attaquant de persister pendant que vous êtes en train de corriger.
Dans la majorité des reprises sérieuses, on agit par étapes :
- mettre le site hors ligne ou en mode maintenance, le temps de travailler sur une copie fiable ; limiter les accès (accès admin, API, FTP, SSH selon le contexte) ; travailler sur une copie, jamais sur le site de production directement ; conserver des traces pour pouvoir prouver ce qui a été fait, quand et comment.
Ce point “sur une copie” semble évident, mais il est facile de le contourner sous pression. Si vous supprimez les fichiers suspects sans conserver d’artefacts, vous perdez la capacité d’expliquer et parfois de corriger ce qui a été manqué.
Constituer un dossier de reprise (preuve et méthode)
Un plan de reprise efficace ne sert pas uniquement à “nettoyer”. Il sert à prouver la validation finale. Pour être concret, on prépare un dossier (dans un espace interne) avec trois types d’éléments : informations d’incident, états techniques, et décisions.
Voici ce que j’inclus systématiquement, parce que c’est ce qui évite les discussions interminables une semaine plus tard :
- captures et export des signaux de compromission (messages des scanners, alertes console, exemples d’URL infectées) ; export des journaux disponibles pendant la fenêtre de risque (au minimum les accès applicatifs, et si possible les erreurs serveur) ; inventaire initial du WordPress attendu (version, liste des thèmes et plugins, versions exactes, configuration sensible) ; identifiant de l’“état propre” le plus probable (date de dernière bonne sauvegarde, ou base de comparaison) ; journal des actions de correction, avec l’heure, le responsable (si équipe), et le résultat observé.
Cette discipline a une valeur opérationnelle immédiate : quand on arrive à la validation finale, on sait quoi vérifier, et surtout pourquoi. On évite aussi la tentation de “retester vite fait” avant de remettre en ligne.
Analyse : retrouver comment ça s’accroche
La désinfection WordPress réussie commence par comprendre les mécanismes de persistance et de déploiement. Souvent, les vecteurs se résument à un petit nombre de catégories, mais les détails changent selon les environnements.
Dans un incident WordPress typique, l’attaquant cherche :
- un point d’entrée (compte admin compromis, plugin vulnérable, thème modifié, fichier upload) ; un moyen d’exécuter du code (fichier ajouté, inclusion conditionnelle, chargement distant) ; une persistance (tâches planifiées, options base de données, fichiers qui se régénèrent).
La difficulté, c’est que les “symptômes” peuvent être trompeurs. Un script malveillant peut être présent uniquement dans une classe d’un thème, mais la charge réelle est en base. À l’inverse, une base infectée peut afficher une page propre tant qu’une extension de thème reste en l’état, puis se mettre à injecter le contenu seulement quand une condition est remplie.
Pour éviter de rater ce genre de scénario, l’analyse doit couvrir à la fois les fichiers et les bases. Même si vous ne trouvez pas tout, vous devez pouvoir éliminer raisonnablement les zones hautement probables.
Plan de reprise : une logique en trois couches
Je pense la reprise en trois couches, du plus destructeur mais fiable au plus fin mais risqué.
1) Restauration contrôlée de la base de code
La méthode la plus fiable, quand elle est applicable, consiste à repartir sur une installation WordPress et un jeu de thèmes et plugins connus, puis à remettre la configuration et le contenu propre.
En pratique, cela veut dire :
- restaurer le core WordPress à partir des sources officielles (ou une base de référence interne contrôlée) ; réinstaller ou vérifier les thèmes et plugins en s’assurant d’avoir des versions propres ; supprimer tout fichier inconnu, surtout dans les répertoires où WordPress n’attend pas d’artefacts additionnels.
Ce que j’appelle “inconnu” n’est pas une obsession paranoïaque. C’est une question de logique. Un plugin légitime peut laisser des fichiers en uploads ou dans son dossier, mais pas des chemins inattendus dans un endroit où le code n’est pas censé s’exécuter. Les attaques exploitent précisément les zones où l’administrateur n’imagine pas que du code puisse vivre.
Trade-off : si votre site a des modifications custom profondes (mu-plugins maison, MU adapté, ou changements de structure), il faut prévoir une stratégie de récupération. Sinon, vous risquez de casser le site au lieu de le réparer.
2) Réconciliation de la base de données
La base est un terrain où les traces sont souvent plus faciles à retrouver, mais où les “nettoyages partiels” peuvent échouer. La base de données porte des indices, par exemple :
- comptes utilisateurs créés ou modifiés ; changements d’options sensibles ; contenu injecté dans des champs d’admin, ou dans des post meta ; fichiers ou chemins malveillants stockés sous forme de configuration.
Le point délicat, c’est que certaines données ne doivent pas être “réinitialisées” sans discernement. Si vous restaurez la base depuis une date antérieure à l’incident, vous risquez de perdre des contenus récents ou des réglages légitimes. Si vous ne restaurez que partiellement, vous risquez d’oublier des vecteurs.
C’est là que la chronologie aide : si vous pouvez estimer la fenêtre de compromission, vous pouvez choisir une restauration qui minimize la perte et maximise la probabilité d’avoir un état cohérent.
3) Désinfection des dépendances et du système de fichiers
Les persistance dans WordPress passent rarement uniquement par une modification ponctuelle du thème. Les charges peuvent être dans des fichiers ajoutés, des scripts dans des répertoires inattendus, ou des mécanismes liés aux uploads.
La couche “système de fichiers” doit donc vérifier :
- l’intégrité des fichiers WordPress et l’absence d’intrus dans les dossiers sensibles ; l’activité et les fichiers dans les zones d’upload ; les tâches planifiées, quand elles existent (par exemple des évènements WordPress) ; la configuration, notamment si des fichiers système ont été touchés ou si les droits ont été relâchés.
Trade-off concret : supprimer des fichiers “bizarres” peut casser des images, des pages, ou des médias qui existaient, mais qui ont été mal nommés. On avance alors avec des critères. Un critère fiable, c’est l’exécutabilité et l’emplacement. Un critère moins fiable, c’est la simple https://gardewp.fr/nettoyage-malware-wordpress/ apparence. Les attaques savent se déguiser.
Mettre le site en régime de preuve, pas en régime de vitesse
Avant de remettre en ligne, l’erreur fréquente consiste à “vérifier le rendu” puis à activer immédiatement. Pour une validation finale crédible, il faut un régime de preuve, une logique de tests orientés risque.
Les tests doivent répondre à deux questions :
- la charge malveillante est-elle encore possible ? la persistance a-t-elle été neutralisée, y compris pour les scénarios où l’injection ne se voit pas immédiatement ?
Quand je travaille, je m’appuie sur une combinaison de contrôles manuels et de vérifications automatisées. Mais je ne confonds pas “un scanner positif” avec une preuve définitive. Les scanners peuvent manquer des comportements conditionnels ou des charges qui s’exécutent seulement dans certains contextes.
Inversement, un faux positif peut vous conduire à une restauration plus destructrice que nécessaire. D’où l’importance de la méthode et des artefacts conservés.
Contrôles spécifiques WordPress : ce qu’il faut valider après correction
Dans la phase de validation, l’objectif est d’assurer que la désinfection WordPress a réellement neutralisé les leviers classiques de compromission. Je me concentre sur des points où l’attaque laisse souvent des traces stables.

Comptes et droits
Si un compte administrateur a été compromis, il peut rester actif même après nettoyage du thème. Il peut aussi avoir été “renforcé” par un changement de mot de passe ou l’activation d’un backdoor via un plugin.
La validation doit inclure un audit des utilisateurs :
- vérifier les nouveaux comptes et ceux avec des rôles élevés ; vérifier l’historique de connexion quand les journaux le permettent ; contrôler les plugins liés à l’authentification ou à la gestion des rôles.
Thèmes et plugins
Les thèmes et plugins sont souvent le point d’entrée ou le point de persistance. Même si vous réinstallez le core, une dépendance infectée peut réintroduire la charge.
La validation doit donc couvrir :
- la liste exacte des plugins et thèmes actuellement activés ; la cohérence des versions avec ce qui est attendu ; la présence de fichiers inattendus dans les dossiers de plugins et thèmes ; la conformité des fichiers “index” et des fichiers qui chargent du PHP.
Base de données
Même après restauration, il faut vérifier les zones à risque dans la base. Les attaques injectent fréquemment via les options ou via des champs de contenu.
En validation, j’aime vérifier des éléments concrets, notamment :
- options modifiées de façon anormale ; présence de code dans des champs qui ne devraient contenir que du texte ; cohérence des identifiants de tables et de leur structure avec une installation normale.
Je garde à l’esprit un détail important : certains sites ont des plugins qui stockent des scripts ou des snippets, ce qui peut déclencher des soupçons. La différence se fait sur la légitimité, l’origine, et la configuration associée.
Plan de validation finale : la checklist que je recommande
Pour transformer la validation finale en quelque chose d’exploitable, j’utilise une checklist courte, orientée preuves. Le but est de ne rien oublier, et surtout de standardiser la décision de remise en ligne.
- Vérifier l’absence d’utilisateurs récents ou inattendus, et contrôler les rôles élevés. Confirmer que le core WordPress et les thèmes/plugins sont ceux attendus, sans fichiers inconnus dans les dossiers sensibles. Contrôler les options et les champs de la base liés aux injections, et vérifier qu’aucun mécanisme de persistance n’est actif. Tester des URLs représentatives (page d’accueil, pages typiques, formulaires, pages dynamiques) depuis un environnement externe, avec cache désactivé si possible. Refaire un scan “à froid” après nettoyage, puis comparer aux résultats antérieurs pour s’assurer que les signaux ont disparu de manière cohérente.
Si un point est incertain, je n’interprète pas l’incertitude comme un “probablement bon”. Je traite l’incertitude comme une raison de prolonger le cycle, soit en analysant une zone, soit en revenant à une restauration plus sûre.
Détail qui change tout : tester depuis plusieurs angles
Un site infecté ne se comporte pas toujours de façon identique pour tout le monde. Les charges conditionnelles utilisent parfois le pays, l’agent navigateur, ou la manière dont la requête est reçue. On peut se retrouver avec un test “OK” dans un navigateur de test, alors que le public voit autre chose.
C’est pour cela que je recommande de tester, en dehors du serveur de test interne, et idéalement :
- en ouvrant le site depuis une connexion différente ; en vérifiant que les pages “silencieuses” sont également clean (pas seulement les pages visibles au premier coup d’œil) ; en contrôlant les formulaires et les redirections, même si elles n’affichent rien à l’écran.
J’ai déjà eu un cas où les pages HTML semblaient normales, mais des liens dans le footer injectaient une redirection uniquement pour des agents mobiles. La correction du thème n’était pas terminée, car un morceau de code conditionnel subsistait.
Validation technique côté navigateur et côté performance
Il peut sembler paradoxal de parler de performance dans un incident de sécurité, mais c’est lié. Un site infecté peut charger des scripts externes de manière conditionnelle. Même si l’injection est “propre” visuellement, elle laisse des traces dans le réseau.
Pendant la validation, je regarde :
- les requêtes réseau inhabituelles au chargement de la page ; la présence de domaines tiers inattendus ; les erreurs JavaScript qui indiquent une charge qui s’exécute puis échoue.
Trade-off : il faut éviter de prendre pour “malveillant” toute ressource tierce. Certains sites légitimes utilisent des tags marketing, des analytics et des services externes. Le contrôle devient donc une comparaison avec le comportement attendu, ou avec une référence avant incident.
Reprise progressive : éviter le retour à l’état fragile
Une fois les contrôles terminés, la remise en ligne peut quand même être risquée si elle se fait brutalement. La reprise progressive réduit la fenêtre d’incident résiduel.
En pratique, je procède par étapes :
- remettre en ligne d’abord en mode limité (par exemple un accès restreint ou un périmètre limité si possible) ; surveiller les logs et les erreurs immédiatement après ; puis ouvrir progressivement le trafic.
Cette méthode a un avantage opérationnel : si quelque chose “revient”, vous le verrez vite, et vous pourrez corriger avant que l’injection ne soit indexée ou signalée.
Prévenir la réinfection : corriger les causes, pas seulement les traces
Nettoyer un site ne suffit jamais si la cause initiale reste là. Il peut s’agir d’un plugin vulnérable non mis à jour, de mots de passe réutilisés, d’une configuration trop permissive, ou d’un manque de séparation des droits.
Sans inventer de solutions universelles, je peux dire ce qui revient le plus dans les reprises :
- mettre à jour les composants (WordPress, thèmes, plugins) dans un ordre cohérent ; supprimer ou désactiver ce qui n’est pas nécessaire ; renforcer la gestion des comptes et limiter l’accès (comptes admin, 2FA si en place, journaux d’authentification quand disponibles) ; vérifier les permissions fichiers et dossiers sur l’espace web ; revoir les mécanismes d’upload, surtout si le site autorise des rôles capables d’installer ou de déposer des fichiers.
Le but est de rendre la persistance plus coûteuse pour un attaquant, et de réduire le temps entre “première intrusion” et “signal exploitable”.
Et la sécurité du prochain incident, comment la mesurer ?
Une validation finale ne doit pas seulement dire “c’est propre maintenant”. Elle doit aussi permettre d’être plus rapide la prochaine fois, et de savoir quoi surveiller.
Je recommande d’installer un suivi après incident, basé sur des éléments concrets :
- l’évolution des logs d’accès et les tentatives de connexion ; l’apparition de nouveaux fichiers dans des emplacements sensibles ; les alertes du système de sécurité ou des outils de scan (tout en gardant une attitude critique sur les faux positifs) ; la surveillance des modifications de fichiers et options, avec des comparaisons.
Ici, le compromis est clair : trop de surveillance peut créer du bruit et fatiguer l’équipe, pas assez laisse passer les signaux. Le bon niveau dépend de votre taille d’exploitation et de votre capacité de réaction.
Choisir entre restauration intégrale et nettoyage ciblé
Une décision fréquente, c’est : je restaure tout, ou je désinfecte uniquement ce qui est compromis ? Dans un monde idéal, la restauration intégrale serait la réponse à tout. Dans le monde réel, elle peut casser des customisations, perdre du contenu récent, ou coûter trop cher.
Mon approche est pragmatique :
- si l’intrusion est profonde, difficile à cartographier, ou multiple, une restauration plus large est plus sûre ; si le problème est localisé, clairement identifié, et que vous pouvez prouver l’absence de persistance ailleurs, un nettoyage ciblé peut suffire.
Le critère clé, c’est la capacité à valider. Si vous ne pouvez pas valider correctement, le nettoyage ciblé est une forme de pari. Et dans la sécurité, le pari se paye souvent en rechute.
Cas limites à ne pas sous-estimer
Certains incidents ne ressemblent pas au “hack classique”.
- Le site semble propre, mais des moteurs signalent des problèmes intermittents. Ici, la charge peut être conditionnelle. Des pages “revenaient” après nettoyage. Cela indique une persistance, parfois via base, parfois via un script qui recrée des fichiers. L’hébergement a été touché au niveau serveur. Dans ce cas, même une désinfection WordPress parfaite peut échouer si les vecteurs restent au niveau infra.
Quand ces scénarios apparaissent, il faut changer de posture : vous ne cherchez plus seulement un fichier malveillant, vous cherchez la dynamique de l’incident. Et cela peut impliquer une collaboration avec l’hébergeur ou une analyse serveur plus approfondie.
Livrable final : ce que vous devez pouvoir expliquer
À la fin, votre validation finale doit produire un résultat exploitable. Il ne suffit pas de “remettre en ligne”. Vous devez pouvoir documenter ce qui a été fait, et pourquoi vous estimez que le risque résiduel est faible.
Je structure ce livrable en deux niveaux, une version interne https://gardewp.fr/ détaillée et une version courte pour les décideurs. Pour garder le plan simple, je m’assure d’inclure des éléments concrets, par exemple :
- les dates et versions appliquées ; les zones nettoyées (core, thèmes, plugins, base, uploads) ; les tests de validation effectués et depuis quels environnements ; les signaux de sécurité “avant” et “après” quand ils existent.
Cette documentation sert autant la sécurité que l’exploitation. Elle réduit les risques de “on a nettoyé, mais personne ne sait comment”, qui est l’un des moteurs des rechutes.
Une désinfection WordPress est un chantier, pas une opération ponctuelle. Le plan de reprise, la validation finale et la preuve par les contrôles font la différence entre un site simplement restauré et un site réellement récupéré. Si vous construisez votre processus autour de la vérification, et pas autour du geste, vous réduisez drastiquement la probabilité de voir l’infection revenir, avec encore plus de dégâts.