Nettoyage fichiers infectés WordPress : rétablir la base de code après altération

Un site WordPress compromis n’a jamais le même visage. Parfois, tout se joue dans l’ombre, une redirection discrète, un encodage bizarre dans un fichier obscure, une page qui charge un script au moment précis où l’internaute clique. D’autres fois, c’est brutal, une chute de trafic en quelques heures, des erreurs 500 partout, ou une vague d’URLs qui ne ressemblent à rien dans les logs.

Quand on suspecte un nettoyage fichiers infectés WordPress, la question la plus difficile n’est pas “comment supprimer ce qui est visible”, mais “comment rétablir la base de code sans aggraver la compromission”. Car une suppression à l’aveugle peut effacer des traces, casser des mises à jour, et surtout laisser un accès persistant derrière une porte qu’on n’a pas vue.

J’ai vu des “nettoyages” menés trop vite avec un résultat frustrant: le site revenait à la normale pendant deux jours, puis repartait en vrille. Souvent, le problème n’était pas seulement le fichier injecté, mais l’environnement autour: comptes admin créés, tâches cron modifiées, fichiers uploadés dans des emplacements inattendus, ou dépendances altérées (thèmes, plugins, parfois même certains core files). L’approche doit être méthodique, et surtout orientée vers la restauration d’un état fiable.

Les premiers signaux qui orientent la recherche

Quand vous ouvrez le serveur pour la première fois, vous avez généralement trois sortes d’indices.

Le premier, c’est ce que vous voyez. Un malware qui imprime une boîte invisible, un script qui ajoute une balise

Sur un cas concret, une équipe marketing m’avait signalé que leurs pages catégories “se chargeaient mais finissaient en erreur”. Dans le navigateur, la page affichait parfois un contenu normal, puis basculait. Les logs montraient un motif récurrent: le même pattern de requête, quelques secondes après le chargement, menant à un fichier modifié dans un thème enfant. Aucun plugin suspect n’était au premier plan, mais la modification était dans un endroit “qui fonctionne même si le site a l’air intact”.

Avant de toucher aux fichiers, je recommande de documenter tout. Pas besoin de faire un rapport lourd, juste noter l’URL touchée, la date de début, le type d’erreur, et vos observations. Ce petit effort fait gagner des heures ensuite, surtout quand il faut valider que le site a réellement été rétabli.

Pourquoi “supprimer l’injection” ne suffit pas

Un fichier altéré est souvent la partie visible d’un mécanisme plus large. Une injection peut être conçue pour survivre à un nettoyage partiel. Par exemple, un script peut réécrire lui-même ses traces au prochain chargement, ou déclencher un téléchargement depuis une source externe selon certaines conditions (user-agent, pays, heure). Dans ce scénario, supprimer la ligne malveillante une première fois donne l’illusion d’un rétablissement, puis l’injection réapparaît dès que le code malveillant a encore de quoi se relancer.

Autre piège fréquent: une modification du core ou des fichiers de thème / plugin, mais aussi une modification de la configuration ou des règles serveur. On pense parfois aux seuls fichiers PHP, alors que des variantes existent: modifications de .htaccess, ajout de rules Apache, ou encore usage d’uploads mal placés. Si vous réparez la “base de code” sans restaurer les fichiers dans leur intégrité, vous ne restaurez pas vraiment la confiance.

La bonne mentalité consiste à viser un état “reproductible”. Un état reproductible signifie: même base installée, même version de WordPress, mêmes thèmes et plugins aux mêmes versions, mêmes configurations vérifiées, et aucune persistance inconnue.

Construire un plan de restauration crédible

Quand je parle de “rétablir la base de code après altération”, j’insiste sur deux mots: base et rétablir.

    Base, parce que WordPress n’est pas juste une ligne de PHP. La base de code inclut le core, les thèmes, les plugins, les fichiers de configuration, les contenus uploadés, et la structure des droits. Une altération dans un sous-dossier peut suffire. Rétablir, parce que l’objectif est de revenir à un état sain, pas seulement de “nettoyer”. Dans un incident, c’est parfois plus rapide et plus sûr de restaurer depuis une source fiable plutôt que de bricoler.

Le piège, c’est de confondre “restaurer” avec “reinstaller tout en laissant les mêmes dossiers”. Si un plugin a été compromis et qu’il reste présent dans le dossier, vous pouvez tout réinstaller par-dessus sans empêcher l’exécution de l’ancien code si le chemin, la version, ou la configuration qui pointe dessus n’est pas alignée.

Dans la pratique, je m’oriente selon un principe simple: soit vous disposez de sauvegardes fiables, soit vous reconstituez la base depuis des sources propres (core WordPress officiel, et versions exactes des thèmes / plugins depuis leurs dépôts d’origine). Sans ça, votre validation devient fragile.

Checklist de triage avant de toucher aux fichiers

Avant toute restauration, je prends quelques minutes pour cadrer la situation. Ce n’est pas du luxe, c’est le moment où vous évitez des erreurs qui coûtent cher ensuite.

    Vérifier l’accessibilité du site et mesurer l’ampleur (pages touchées, temps de chargement, erreurs 500). Relever une liste des fichiers modifiés récemment (dates et chemins) et conserver les indices. Contrôler les comptes WordPress: utilisateurs, rôles, derniers accès, et actions récentes. Inspecter la configuration à risque (notamment wp-config.php, .htaccess, et la configuration serveur associée). Isoler l’accès au serveur pendant l’enquête si possible (au moins limiter temporairement l’upload et l’administration).

Cette étape n’a pas vocation à être exhaustive, mais elle vous empêche d’entrer dans un mode “suppression au hasard”.

La méthode la plus sûre: restaurer depuis une source fiable, puis revalider

Il existe plusieurs niveaux d’intervention. Le plus prudent est aussi celui qui prend le plus de temps au début, mais qui évite souvent des retours en arrière.

Rétablir le core WordPress

Le core est un bon candidat pour la restauration intégrale. Si vous avez une installation standard, le core peut être replacé à l’identique à la version installée. Ce geste ne remplace pas tout, mais il retire une zone d’incertitude.

En pratique, on travaille souvent sur une copie du site, pas sur la production. Sur un incident que j’ai géré pour une boutique en ligne, la restauration du core sur la production a d’abord “corrigé” le symptôme, puis les problèmes ont refait surface ailleurs. Le retour a révélé que l’altération venait de thèmes et de configurations. La production avait été modifiée trop tôt, et l’équipe n’avait plus de fenêtre pour comparer. Depuis, je privilégie toujours une copie de travail.

Refaire une base saine pour thèmes et plugins

WordPress n’exécute pas le “thème” au sens large seulement. Il exécute des fichiers précis dans des sous-dossiers. Un malware peut se cacher dans un fichier de template, dans un hook, dans un fichier inclus conditionnellement, ou dans un script chargé depuis une page.

Donc, la restauration de thèmes et plugins est rarement un “patch”. Elle ressemble plutôt à une réinstallation contrôlée des versions. Si le thème provient d’un vendeur, vous devez idéalement le reprendre à la version connue (celle de votre déploiement initial, ou celle que vous aviez avant l’incident). Si vous avez un thème enfant, il faut aussi vérifier que le parent n’est pas altéré.

Pour les plugins, même logique. https://gardewp.fr/ Si un plugin est compromise, le supprimer est parfois une solution immédiate, mais ça peut aussi casser un site qui repose dessus. D’où l’intérêt de travailler avec une restauration contrôlée, puis une réactivation progressive.

Garder vos contenus, pas vos scripts malveillants

Les médias et contenus (wp-content/uploads) peuvent contenir des fichiers malveillants. Parfois, des fichiers PHP sont injectés dans des dossiers d’upload, parfois ce sont des scripts camouflés. Il faut distinguer: les images et fichiers légitimes, et les fichiers qui ne devraient pas être là.

Un point crucial: si vous restaurez wp-content intégralement depuis une sauvegarde saine, vous sécurisez aussi vos uploads. Mais si la sauvegarde n’est pas saine ou si elle date de trop loin, vous risquez de remettre l’infection. Ici, le “timing” compte. Quand vous avez plusieurs sauvegardes, vous devez choisir celle qui précède l’incident, et qui a été validée.

Inspection ciblée: où l’infection se cache le plus souvent

Sans promettre de retrouver “toujours la même chose”, il y a des zones qui reviennent dans les incidents réels.

Je regarde en priorité les fichiers PHP ajoutés ou modifiés récemment, mais aussi certains emplacements classiques:

    des fichiers dans des thèmes et plugins, surtout ceux qui ne devraient pas contenir de logique d’exfiltration ou de redirection, des variations autour des hooks WordPress, dans les fichiers qui s’exécutent tôt, les modifications de .htaccess, qui peuvent changer la façon dont des requêtes sont traitées, des changements dans wp-config.php, parfois indirects (par exemple une constante qui active une URL externe).

Un détail que j’ai appris à respecter: une infection peut être très petite, une dizaine de lignes. Elle peut utiliser des méthodes “discrètes” pour réduire les faux positifs des scanners. Donc l’inspection se fait en parallèle avec des heuristiques: chaînes inhabituelles, URL externes non liées à votre activité, encodages répétitifs, appels à des fonctions de chargement de fichiers inattendus.

image

Valider après restauration: la sécurité, c’est aussi la preuve

Restaurer ne suffit pas si vous ne validez pas. Dans l’idéal, vous testez avant de remettre en production. Dans la réalité, vous pouvez avoir besoin de rétablir vite, mais la validation reste indispensable.

Je fais typiquement trois niveaux de vérification.

Le premier est la validation “fonctionnelle”. Est-ce que les pages normales fonctionnent, sans redirections, sans chargement de ressources externes inattendues, sans erreurs visibles?

Le second est la validation “technique”. Les pages retournent-elles un code HTTP cohérent, sans erreurs aléatoires. Les logs montrent-ils encore des requêtes vers des chemins inattendus. Vous pouvez aussi vérifier les erreurs PHP.

Le troisième est la validation “intégrité”. On recompare ce qui a été restauré à une source fiable, et on s’assure que l’horodatage et les tailles correspondent globalement. Un fichier qui a l’air identique mais dont la taille ou l’horodatage ne colle pas parfaitement peut indiquer qu’un patch a été appliqué après coup.

C’est là qu’une approche “tout restaurer” montre son avantage. Si vous remplacez core, thèmes et plugins par des versions propres, et que vous gardez uploads sous contrôle, vous réduisez le champ d’erreur.

Cas typiques et arbitrages concrets

Dans un incident, vous serez confronté à des décisions, et ce sont ces décisions qui déterminent si le retour à la normale tient.

Cas 1: sauvegardes disponibles mais incomplètes

Vous pouvez avoir une sauvegarde “base de fichiers” mais pas une sauvegarde complète de la base de données, ou l’inverse. Sans entrer dans des détails trop techniques, retenez l’idée: restauration partielle peut laisser des incohérences. Si des options WordPress, des paramètres plugin, ou des utilisateurs compromis existent dans la base, vous pouvez rétablir le code et laisser la persistance.

Dans ce cas, je préfère une stratégie de réduction du risque: réinstaller le code propre, puis traiter la base de données avec une validation stricte des éléments sensibles. C’est plus long, mais ça évite le scénario “le site charge, mais il est encore piloté par des valeurs compromises”.

Cas 2: infection qui se réplique

Quand l’injection réapparaît, ce n’est pas juste un fichier malveillant, c’est une mécanique de persistance. Souvent, cette mécanique passe par un rôle utilisateur, un accès FTP ou SSH toujours actif, ou un job planifié.

La restauration doit alors inclure une action sur les vecteurs. Même si vous remplacez les fichiers, si un compte admin est resté et que la base contient des hooks malveillants, le problème revient. La validation de la base utilisateur et des tâches planifiées fait partie de la réponse, pas seulement l’inspection du dossier.

Cas 3: thème enfant et personnalisations indispensables

Si vous avez un thème enfant très personnalisé, restaurer le thème parent ou le thème enfant peut créer des écarts visuels ou fonctionnels. D’où l’arbitrage: vous pouvez restaurer parent et conserver enfant uniquement après validation d’intégrité et suppression des sections suspectes.

Ici, la nuance compte. Un fichier de thème peut contenir du code légitime, par exemple des hooks de performance ou des ajouts de styles. Donc l’enjeu n’est pas seulement “supprimer tout ce qui ressemble à du malware”. L’objectif est de comparer, comprendre ce que vous aviez avant, et supprimer ce qui a été ajouté ou altéré sans justification.

Quand je n’ai pas de version “saine” avant incident pour le thème enfant, je demande au client de retrouver un dépôt, un zip, ou une archive de déploiement antérieure. Sans ça, je privilégie une remise à zéro du thème enfant, puis une réintégration des modifications une par une. C’est pénible, mais c’est souvent plus fiable que de deviner ce qui est “normal”.

Ne pas tomber dans les faux gagnants: scanners, plugins “curatifs”, et confiance excessive

Les scanners automatisés sont utiles, mais ils ne remplacent pas la validation. Un faux positif peut vous faire supprimer un code réellement légitime. Un faux négatif, lui, laisse une infection passer.

J’ai vu un site “nettoyé” parce qu’un plugin de sécurité avait trouvé trois signatures. Après restauration du code, tout semblait propre. Deux semaines plus tard, un nouveau schéma d’injection a été détecté. Le point commun: le vecteur initial, un accès persistant ou une base de données encore corrompue, avait survécu.

Donc, oui, utilisez les outils. Mais traitez-les comme des boussoles, pas comme une preuve. La preuve, c’est votre capacité à revenir à un état cohérent: versions alignées, fichiers remplacés par du propre, utilisateurs et configurations contrôlés, uploads inspectés.

Éviter la recontamination: fermer les portes pendant que vous travaillez

Même après restauration, il faut empêcher l’adversaire de revenir. Sinon, vous nettoyez une première fois, puis vous recommencez.

La recontamination vient souvent d’un accès qui n’a pas été révoqué, de mots de passe faibles, d’une session maintenue, ou d’un canal d’upload toujours ouvert. Parfois, c’est aussi un compte technique, un compte FTP ou une clé SSH, qui a été compromis.

Dans l’urgence, je fais en sorte que les accès soient “parés”. Je demande au client de changer les mots de passe, de vérifier les sessions, de supprimer les comptes non reconnus, et de vérifier les rôles. Si l’hébergement permet de tracer les connexions, je contrôle aussi les IP inhabituelles.

Comparatif rapide des stratégies

| Stratégie | Quand ça marche | Risque principal | Temps | |---|---|---|---| | Suppression ciblée uniquement des fichiers suspects | Petites injections, preuve claire, sauvegarde saine proche de l’incident | Persistance ailleurs, infection qui se réplique | Faible à moyen | | Restauration core seulement | Infection limitée au core, symptômes isolés | Thème ou plugin toujours compromis | Moyen | | Restauration core + thèmes + plugins par versions propres | Quand vous voulez une base “reproductible” | Besoin de retrouver des sources fiables des thèmes/plugins | Moyen à élevé | | Restauration complète code + vérification base + contrôle accès | Incidents persistants ou récurrents | Demande plus de coordination (DB, fichiers, accès) | Élevé |

Cette table n’est pas une vérité universelle. Sur certains environnements, restaurer tout est plus risqué à cause des intégrations spécifiques. Mais dans la majorité des cas, plus vous réduisez le champ des incertitudes, plus le retour à la stabilité est solide.

Un mini-plan d’action, étape par étape (sans perdre de temps)

Je ne vais pas vous noyer dans une procédure de type “cliquer partout”. En revanche, voici un déroulé court, réaliste, que j’utilise quand il faut agir vite tout en gardant la rigueur.

    Isoler l’incident, copier l’environnement, puis travailler hors production si possible. Restaurer le core, puis replacer thèmes et plugins par versions propres et vérifiées. Inspecter wp-content/uploads et les emplacements où des fichiers inattendus auraient pu être déposés. Revoir utilisateurs et rôles, ainsi que les points de persistance dans la base (et les tâches planifiées si présentes). Mettre en production, surveiller logs et comportement, puis répéter une validation d’intégrité après les premières heures.

Ce plan tient parce qu’il protège contre les “surprises”, celles qui viennent après coup.

Surveiller les traces dans les premières heures après retour en production

Les heures qui suivent la restauration sont celles où vous détectez si l’infection était encore vivante. Même si tout a l’air bon, je conseille de garder une surveillance active au moins sur un petit créneau.

Vous cherchez surtout des signaux de réactivation: nouveaux fichiers créés, modifications de fichiers à nouveau, connexions suspectes, et comportements anormaux côté navigateur (chargement d’un script externe inconnu, redirections, changements d’en-têtes).

image

Un exemple concret: un site d’annonces avait l’air normal après restauration, mais un pic de requêtes vers un fichier PHP “nouveau” a été observé deux heures plus tard. La source était un compte admin qui avait été rétabli. Les identifiants avaient été changés, mais un ancien rôle ou une session existait encore. Le correctif a été rapide, mais uniquement grâce à la surveillance.

Pourquoi certaines “récupérations” semblent réussies avant de rechuter

Quand ça rechute, la cause est rarement mystérieuse. Elle ressemble à ceci:

    un vecteur persistant a survécu dans la base (un utilisateur, une option, un mécanisme de planification), un fichier n’a pas été remplacé par une source vraiment saine, le site se reconstruit avec le temps via un plugin ou une intégration qui exécute de nouveau le code altéré, ou une partie des uploads a été restaurée depuis un état infecté.

Le point essentiel: un incident se mesure dans la durée, pas dans la minute où tout semble fonctionner.

image

Résoudre sans casser: le rôle des versions et de la cohérence

La restauration n’est pas seulement une question de sécurité, c’est aussi une question de cohérence technique.

Si WordPress est en version X, et que vous remplacez le core par une version Y, vous pouvez provoquer des différences inattendues. Si vos thèmes sont dépendants de fonctions d’une version, vous pouvez aussi créer des erreurs. Pareil pour les plugins, qui changent souvent leurs hooks au fil des versions.

C’est pour ça que l’équipe d’un hébergement ou un développeur doit connaître l’écosystème exact au moment de l’incident. Quand le site est en production depuis longtemps, il arrive que l’information “version exacte des plugins” manque ou soit difficile à reconstituer. Dans ce cas, je fais une reconstruction par preuves: historiques du site, archives de déploiement, traces de logs, et sources fournies par le client (ou par les développeurs).

Ce travail peut sembler long, mais il réduit le risque d’un retour en arrière fonctionnel après restauration.

Garder une approche “propre” pour la suite

Une fois le site rétabli, vous voulez éviter que le scénario se répète. Sans transformer ça en cours théorique, je recommande surtout de transformer l’incident en posture de maintenance:

    réduire les privilèges (les comptes administrateurs ne devraient pas servir aux tâches quotidiennes), limiter les plugins inutiles, surveiller les mises à jour, et renforcer la gestion des accès à l’upload.

Le nettoyage fichiers infectés WordPress n’est pas une action ponctuelle si le socle de sécurité reste inchangé. Une bonne récupération, c’est aussi un ajustement des habitudes.

Ce que j’attends d’une “base de code rétablie”

Quand je suis satisfait d’un rétablissement après altération, je peux répondre à trois questions simples.

Première question: le code chargé par WordPress correspond-il à une base saine, cohérente avec vos versions installées? Deuxième question: les points de persistance connus ont-ils été neutralisés (comptes, rôles, tâches, configurations)? Troisième question: le comportement du site après retour en production ne montre-t-il pas de redirections, de ressources externes anormales, ou d’erreurs récurrentes?

Tant que ces réponses ne sont pas solides, je considère que le risque n’est pas neutralisé. Et dans un incident réel, “ça marche” n’est pas un critère suffisant. Il faut “ça marche et ça reste stable”.

Si vous êtes en plein milieu d’un incident, je peux vous aider à structurer la démarche selon votre contexte: vous avez des sauvegardes? Quel hébergement (contrôle panel, accès SSH)? Quelles versions WordPress, thèmes, plugins? Et quels symptômes précis (redirections, erreurs, scripts chargés)? Avec ces éléments, on peut choisir la stratégie de restauration la plus adaptée, sans partir sur des suppositions.