Suppression de code malveillant dans WordPress : procédure de nettoyage

Quand un site WordPress se fait injecter du code malveillant, la première réaction est souvent de vouloir “tout supprimer” et de repartir proprement. En pratique, c’est plus compliqué, parce que l’infection n’a pas seulement une forme visible. Parfois, elle se cache dans un plugin ou un thème abandonné, parfois dans un fichier image ou dans une option de base de données, et parfois dans des accès utilisateurs qui n’ont rien à voir avec l’administrateur principal. J’ai déjà vu des sites “propres” en apparence, mais qui continuaient d’envoyer des requêtes depuis l’ombre toutes les heures. D’un côté, on veut nettoyer vite. De l’autre, on doit conserver les preuves et éviter d’aggraver les dégâts.

Ce billet décrit une procédure de nettoyage réaliste, celle que j’utiliserais en tant qu’intervenant, avec des choix prudents, des contrôles, et des limites claires. L’objectif est de supprimer le code malveillant, mais surtout de comprendre d’où il vient pour ne pas réinfecter votre site dès le prochain déploiement.

Comprendre ce que vous combattez, avant de toucher au site

La “malveillance” sur WordPress n’est pas un malware unique. Elle correspond à plusieurs familles de comportements: redirections, ajout de scripts sur les pages publiques, chargements de ressources externes depuis des domaines douteux, modifications de fichiers noyau ou de fichiers ajoutés, altération des formulaires, création de comptes discrets, ou encore manipulation de la base (options, cron, tâches planifiées, tables tables de cache).

Avant toute suppression, il vaut mieux cadrer les symptômes, car ils orientent le diagnostic. Quelques signaux reviennent souvent quand on cherche à nettoyer site WordPress infecté :

    des pages qui changent sans raison apparente, surtout sur certaines URL un trafic “bizarre” dans les outils d’analyse, avec des pics nocturnes des alertes dans les navigateurs, ou des avertissements Google Search Console des erreurs PHP ou des chaînes de caractères étranges dans des fichiers que vous n’avez pas touchés des nouveaux utilisateurs, voire des droits trop élevés donnés à des comptes inconnus

Je conseille de noter tout ce que vous observez, avec date et heure. Cela ne sert pas à “faire joli”, cela sert à corréler les étapes de nettoyage avec l’évolution du comportement.

Stopper l’hémorragie, sans détruire vos preuves

Si votre site est compromis, la priorité n’est pas de tout corriger immédiatement, c’est d’éviter de continuer à diffuser le code injecté pendant l’investigation.

Dans la plupart des cas, vous pouvez mettre le site en maintenance. Sur WordPress, un mode maintenance propre évite aussi que votre serveur continue à servir des pages altérées aux visiteurs. Attention néanmoins à un point: si l’infection repose sur des requêtes déclenchées par le trafic, la réduction de trafic peut masquer certains symptômes. C’est un compromis. À mon sens, le bon équilibre consiste à mettre en maintenance, puis à effectuer vos contrôles avec des requêtes contrôlées (votre IP, un navigateur de test), plutôt que laisser tout le monde consommer une version compromise.

Ensuite, faites une copie de sauvegarde complète. Pas un export partiel. Une copie du répertoire WordPress, plus la base de données, et idéalement une copie des fichiers d’uploads séparément si vous avez un schéma de stockage complexe. Si vous êtes en mutualisé, une sauvegarde “automatique” du fournisseur peut exister, mais elle n’est pas toujours assez granulaires au moment de remonter une chronologie. Si vous êtes sur un VPS ou un serveur dédié, la copie de l’intégralité du contenu avant modification devient une routine.

Isoler la source probable: fichiers, base de données, ou compte compromis

Une infection WordPress se manifeste souvent dans un seul endroit, mais elle peut aussi être “multi-couches”. J’utilise une logique simple: vérifier d’abord les trois zones classiques, dans l’ordre où elles produisent le plus d’indices.

1) Les fichiers modifiés

Les injections de code se voient parfois dans des fichiers du thème, dans des plugins, ou dans des fichiers “techniques” ajoutés à la racine. Un classique est l’altération de fichiers inclus indirectement, comme des fichiers chargés via require, des hooks, ou encore des templates spécifiques.

Le piège: ne pas chercher uniquement du “code PHP visible”. Certaines infections stockent une charge utile dans une zone inattendue, puis l’exécutent via une fonction de rappel, ou encodent le contenu. D’où l’intérêt de comparer avec une référence “saine”.

2) La base de données

Certaines charges malveillantes ne touchent pas les fichiers du site. Elles modifient des options, ajoutent des lignes dans des tables de configuration, modifient le cron, ou stockent du code dans des champs qui finissent par être affichés côté front.

C’est particulièrement important si vous avez déjà vu des fichiers “vierges”, mais que le site affiche quand même du contenu indésirable. Dans ce cas, le nettoyage doit inclure la base, pas uniquement les thèmes et plugins.

3) Les comptes et permissions

Une fois l’accès compromis, la réinfection arrive vite. Les pirates peuvent créer des comptes, ou modifier les rôles. Parfois, le compte admin semble normal, mais il existe un compte “éditeur” ou “auteur” ajouté il y a quelques semaines, que vous n’avez jamais revu. Ils peuvent aussi modifier les clés d’API, ou les identifiants utilisés par des plugins tiers.

Préparer l’analyse: outils et méthodes qui évitent les faux positifs

Il existe une jungle d’outils, mais votre but n’est pas de “trouver du code suspect” au hasard. Votre but est de confirmer l’intention malveillante, et de localiser ce qui a changé.

image

L’idée la plus saine est d’avoir un état de référence propre. Si vous avez une sauvegarde antérieure à l’infection, vous pouvez comparer. Sinon, vous pouvez comparer vos fichiers actifs à une distribution officielle de WordPress du même numéro de version, en ignorant les dossiers qui changent naturellement (uploads, thèmes sur mesure, etc.).

Côté analyse, j’utilise généralement trois approches simultanées:

Comparaison de fichiers modifiés récemment, via l’historique de vos déploiements ou via les dates de modification Recherche de signatures (mots ou patterns) qui reviennent dans beaucoup d’injections, en gardant à l’esprit que toutes les signatures ne sont pas universelles Inspection des “points d’exécution”, donc les hooks, les includes, les fichiers appelés au chargement d’une page

On tombe vite dans le piège des faux positifs. Par exemple, un plugin peut contenir du code “bizarre” sans être malveillant, notamment s’il utilise des fonctionnalités de compression, d’obfuscation ou de minification. Le bon réflexe, c’est de regarder le contexte: est-ce que le code modifie quelque chose côté affichage, est-ce qu’il appelle des URLs externes, est-ce qu’il interagit avec eval, base64_decode, ou des fonctions dangereuses, est-ce qu’il manipule $_POST, $_COOKIE, ou des variables serveur de manière anormale.

Première passe de nettoyage: thèmes et plugins, au lieu de toucher au noyau au hasard

Sur WordPress, la méthode “je remplace tout” peut sembler efficace, mais elle peut aussi effacer vos modifications légitimes. La stratégie la plus robuste consiste à neutraliser d’abord ce qui a le plus de chances d’être compromis: les plugins et thèmes tiers, puis à restaurer uniquement ce qui a été altéré.

Avant de supprimer, vérifiez l’état réel:

    la liste des plugins actifs et récemment installés les mises à jour effectuées récemment, surtout celles faites en dehors de votre calendrier habituel les thèmes installés et leurs fichiers modifiés

Ensuite, vous pouvez désactiver tous les plugins, puis réactiver un par un, mais seulement si l’accès au back-office est sûr et si vous contrôlez les symptômes. Si vous suspectez une infection dans le code qui s’exécute au chargement public, la désactivation côté admin peut ne pas suffire. Dans certains cas, vous devrez travailler par accès fichiers, en renommant le dossier plugins ou en replaçant des copies.

Si vous décidez de remplacer un thème, je recommande de ne pas “patcher” le code suspect à la main. À la place, supprimez, réinstallez depuis la source officielle, ou restaurez depuis une sauvegarde saine. Toucher au code d’un thème compromis “pour corriger quelques lignes” laisse souvent des résidus, et vous perdez la piste de ce qui a changé.

Checklist de triage rapide (avant suppression définitive)

Quand vous devez nettoyer vite, sans improviser, cette petite checklist vous évite des erreurs fréquentes. Elle ne remplace pas l’analyse, elle la rend efficace.

Mettre le site en maintenance et sauvegarder fichiers + base avant toute modification Identifier la dernière fenêtre d’activité: dernière mise à jour, dernier déploiement, date d’apparition des symptômes Vérifier utilisateurs: nouveaux comptes, rôles inhabituels, et champs de profil modifiés Comparer fichiers suspects: thèmes, plugins, dossiers racine, scripts ajoutés, fichiers récemment modifiés Contrôler la base: options, cron, éventuels contenus injectés dans des champs affichés

Supprimer le code malveillant: procédure pas à pas (avec marges de sécurité)

Voici une procédure que j’applique dans un ordre qui limite le risque de réinfection pendant que vous corrigez.

Étape 1: verrouiller l’accès et sécuriser les identifiants

Tant que l’attaque peut réutiliser des identifiants volés ou des sessions, vous allez travailler dans le brouillard. Commencez par:

    changer les mots de passe des comptes ayant des rôles élevés invalider les sessions si votre environnement le permet vérifier le fichier wp-config.php pour détecter d’éventuels changements, même si ce n’est pas le plus fréquent

Je fais aussi une vérification des clés de sécurité WordPress, car dans certains incidents, elles sont modifiées pour faciliter la persistance. Ce n’est pas une règle universelle, mais c’est un point à contrôler.

Étape 2: restaurer ou remplacer le noyau WordPress

Même si le noyau n’est pas le vecteur principal, je préfère le restaurer depuis une version officielle correspondant au numéro exact de votre WordPress. Cela supprime les modifications “collatérales” et réduit la surface d’infection.

Attention: ne supprimez pas la racine à la légère. Utilisez une stratégie de remplacement ciblée: remplacez les fichiers du noyau, sans écraser vos wp-content et sans toucher aux uploads. Mais vérifiez aussi ce qui peut être injecté dans des fichiers de configuration ou de chargement, car certains attaquants ne se contentent pas de wp-admin ou wp-includes.

Étape 3: assainir wp-content, dans l’ordre probable des vecteurs

Ensuite:

    remplacez thèmes et plugins par des versions propres supprimez les thèmes et plugins non utilisés, surtout s’ils sont anciens ou abandonnés vérifiez l’historique de fichiers: des scripts ajoutés dans des dossiers “bizarres” (par exemple un fichier dans uploads qui n’a pas de raison d’y être)

Sur les infections récentes, on voit https://gardewp.fr/ parfois des charges logées dans des fichiers qui semblent inoffensifs par leur extension. N’ouvrez pas et n’exécutez pas, au sens propre. Le but est de supprimer ce qui n’a pas de place.

Étape 4: nettoyer la base de données avec prudence

Vient ensuite la base. C’est souvent la partie la plus sensible, car vous pouvez casser le site en nettoyant trop ou trop vite.

Ce que je fais en premier, c’est vérifier les tables où l’on trouve des traces d’injection: options liées à des événements planifiés, contenus qui ressemblent à des fragments de code, et données qui déclenchent des comportements automatiques.

Le principe: si vous voyez une option ou une entrée qui stocke un script ou une redirection externe inhabituelle, vous l’isolez, vous l’expliquez, puis vous supprimez ou vous restaurez. Si vous n’êtes pas certain, vous comparez avec une sauvegarde saine.

image

Évitez la suppression à l’aveugle. WordPress utilise énormément d’options et certains plugins enregistrent du contenu compressé. Le bon réflexe est de cibler uniquement les éléments manifestement incohérents ou liés aux symptômes observés.

Étape 5: retirer les utilisateurs indésirables et corriger les rôles

Ensuite, je reviens au volet comptes.

    supprimez les comptes créés pendant ou juste avant l’apparition des symptômes, si vous n’avez aucune preuve qu’ils sont légitimes vérifiez les rôles et les capacités contrôlez aussi les comptes “silencieux” qui n’ont pas forcément activement publié du contenu, ils peuvent juste servir de portes arrière

Si vous constatez qu’un compte se recrée automatiquement après suppression, c’est un indicateur d’un mécanisme de persistance basé sur un hook, un cron compromis, ou une tâche côté serveur. Dans ce cas, revenez en arrière sur les étapes base et planification.

Étape 6: vérifier la persistance dans les tâches et le serveur

WordPress dispose d’un système de tâches planifiées, et certains hébergeurs ajoutent leurs propres cron. Les infections sérieuses exploitent souvent ces mécanismes pour réinjecter le code.

Il faut donc vérifier:

    les tâches cron de WordPress, via l’admin si accessible, ou via la base de données si nécessaire les cron système du serveur, si vous avez accès, en regardant ce qui tourne à intervalles réguliers les scripts uploads qui peuvent déclencher des appels réseau

Quand j’ai géré un incident similaire, le code malveillant n’apparaissait pas dans les fichiers du thème, mais revenait toutes les 30 minutes via un cron interne. Le nettoyage “fichiers” avait été fait correctement, mais la persistance restait. Une fois le cron retiré, l’infection a cessé.

Contrôler le résultat: tests avant de réouvrir au public

Une fois que vous pensez avoir nettoyé, vous ne validez pas “à l’œil”, vous validez par test.

Je fais généralement une série de tests ciblés, depuis un navigateur en mode navigation privée, et aussi depuis un outil de requêtes automatisées:

    vérifier plusieurs pages, pas seulement la page d’accueil, car certains payloads ciblent des templates précis vérifier le HTML source, à la recherche de scripts ajoutés, de balises inattendues, ou de ressources externes vérifier les redirections, en testant les URL suspectes et des liens internes depuis la navigation surveiller les logs d’erreurs PHP et les logs d’accès pendant les tests

Il y a un indicateur assez parlant: pendant vos tests, si le site émet des requêtes vers des domaines connus pour être malveillants, ou si des codes d’erreur apparaissent, ce n’est pas encore stabilisé.

Durcir WordPress après nettoyage, pour éviter la réinfection

Le nettoyage résout le problème immédiat, mais pas forcément la cause. Si la cause est un accès compromis, un plugin obsolète, ou des mots de passe faibles, vous rebasculerez.

Le durcissement ne doit pas être compliqué, mais il doit être cohérent avec votre réalité d’exploitation.

Voici les leviers que je privilégie, sans faire de promesses irréalistes:

    supprimer les plugins et thèmes inutiles, surtout ceux non maintenus mettre à jour le cœur WordPress, les thèmes et plugins dès que possible renforcer les mots de passe et activer l’authentification forte si vous le pouvez limiter les permissions de l’utilisateur quotidien, et réduire le nombre de comptes administrateurs surveiller les changements de fichiers (même un monitoring basique peut vous alerter en cas d’écart)

Je place aussi un contrôle régulier de la base de données et des utilisateurs. On ne parle pas de paranoia, on parle de signal. Les incidents ont rarement un seul symptôme.

Cas fréquent: “je n’ai trouvé aucun code suspect dans les fichiers”

Ce cas arrive, et il est plus fréquent qu’on ne le croit. Si vous ne trouvez pas d’injection évidente dans les fichiers, les deux causes principales sont la base de données ou un accès persistant ailleurs.

Dans ces situations, j’oriente l’investigation vers:

    les options et contenus en base qui déclenchent l’injection dans le front le cron, car il peut être le vecteur principal un plugin présent mais “proche du vôtre”, qui exécute une charge à peine visible

Parfois, le code est minifié ou encodé, et vos recherches de mots-clés ne suffisent pas. Dans ce cas, l’approche la plus fiable est de comparer votre base à une sauvegarde saine, et de réduire le scope au strict nécessaire.

Cas fréquent: “le site est propre, mais Google ou le navigateur alerte encore”

Il peut y avoir un décalage entre la désinfection et les caches ou les signalements. Si vous avez une infection détectée via des outils de sécurité, ils peuvent garder l’ancienne trace un moment, le temps de recrawler ou de mettre à jour les bases internes.

Ici, la bonne démarche est de prouver la stabilité côté contenu et de soumettre la demande de réexamen quand cela est pertinent. Je n’assure pas les délais, ils varient selon l’origine de l’alerte et le niveau de suspicion conservé. Mais vous réduisez fortement le temps de récupération en gardant le site stable et propre pendant la période de vérification.

Surveiller après réouverture: les indicateurs qui comptent

Une fois le site réouvert au public, le risque baisse, mais il n’est pas nul. L’objectif est de repérer une réinfection tôt, avant qu’elle ne se généralise.

Je recommande de:

    surveiller les tentatives de connexion, surtout sur les endpoints d’identification regarder les pics de trafic anormaux et les redirections contrôler les nouveaux fichiers dans wp-content/uploads et la création de fichiers inattendus vérifier que les plugins nouvellement installés ne réapparaissent pas

Si vous remarquez un comportement identique à celui d’origine, vous revenez immédiatement sur la base, sur les tâches planifiées, et sur les comptes. La persistance revient presque toujours par un de ces chemins.

Tableau mental des priorités: quoi traiter en premier, quand le temps manque

Quand vous êtes sous pression, il est facile de se perdre dans les détails. J’utilise cette hiérarchie intuitive: ce qui permet d’arrêter la réinfection tout de suite, puis ce qui élimine les vecteurs probables, puis ce qui restaure une confiance durable.

    accès et utilisateurs planification et persistance fichiers de thème et plugin base de données ciblée noyau WordPress restauré

Cette approche ne remplace pas l’enquête, mais elle limite les erreurs de séquence.

Erreurs classiques à éviter pendant le nettoyage

J’ai vu des nettoyages “courts” qui finissent par coûter plus cher que prévu.

La première erreur, c’est de supprimer des fichiers sans comprendre ce qui les appelle. Vous cassez alors un mécanisme légitime ou vous supprimez uniquement la couche visible, pendant que la persistance reste en base.

La deuxième erreur, c’est de restaurer uniquement wp-content/uploads ou uniquement les thèmes, en oubliant la base ou les tâches planifiées. Le site semble revenir, puis rechute.

image

La troisième erreur, c’est de changer un mot de passe sans invalider l’accès ailleurs. Certaines sessions ou clés persistent selon l’environnement. Tant que l’accès n’est pas verrouillé, vous perdez du temps.

Quand faire appel à un spécialiste, et quand vous pouvez agir seul

Si votre site est petit, que vous avez une sauvegarde saine et que l’infection est localisée, un nettoyage en interne peut fonctionner. Dans d’autres cas, c’est un faux gain. Vous pouvez vous retrouver à corriger des symptômes sans traiter la cause, et vous finissez par devoir tout reconstruire.

Je pense qu’il faut envisager un support externe si:

    vous n’avez pas de sauvegarde saine et que vous ne pouvez pas comparer vous suspectez une compromission plus large que WordPress (accès serveur, tâches système) vous ne pouvez pas analyser la base de manière prudente le site est critique pour votre activité, et le risque de récidive est trop coûteux

Dans tous les cas, même quand vous faites intervenir quelqu’un, documentez. Une infection WordPress n’est pas seulement un “problème technique”, c’est une séquence d’événements. Les notes sur les dates et les changements accélèrent énormément la résolution.

Réalité opérationnelle: nettoyer site WordPress infecté, c’est aussi retrouver une routine

Le point important, c’est que la procédure de nettoyage n’est pas un événement isolé. C’est le moment où vous mettez en place une discipline. Si vous ne changez rien ensuite, l’incident se répète sous une autre forme.

Après un nettoyage, je conseille toujours de planifier:

    une revue des plugins et thèmes, avec suppression de ce qui n’est pas indispensable une mise à jour planifiée du cœur et des extensions une stratégie de sauvegardes testées, pas seulement “activées” une surveillance de base du site (fichiers et logs)

Avec ces mesures, vous passez d’une gestion en mode urgence à une gestion en mode maintenance, ce qui change tout.

Si vous voulez, décrivez votre contexte (version WordPress, plugins récents, symptômes exacts, et si vous avez une sauvegarde antérieure). Je peux vous aider à orienter la procédure, notamment sur la recherche de persistance et la stratégie de nettoyage de la base de données, sans faire de manipulations risquées à l’aveugle.