Site WordPress infecté : purger cache et CDN après restauration

Quand un site WordPress a été infecté, on a tendance à se focaliser sur la “réparation” au sens strict, c’est-à-dire nettoyer les fichiers, corriger les comptes, vérifier la base de données et colmater la faille. Pourtant, il y a une étape qui revient souvent, même quand le chantier de reprise a été fait proprement : la purge du cache, et surtout celle du CDN.

Le piège est simple et très frustrant. Vous restaurez un site “propre” à partir d’une sauvegarde, vous contrôlez les traces évidentes, puis vous constatez que des visiteurs voient encore des contenus injectés, des redirections bizarres ou des versions anciennes du site. Parfois, ce n’est pas que la restauration a échoué. C’est que le cache sert encore la version infectée, ou pire, qu’il sert une version qui n’aurait jamais dû être exposée.

Dans ce contexte, l’expression “site WordPress infecté,” n’est pas qu’un mot-clé. C’est un scénario opérationnel. Et la purge cache et CDN devient une partie intégrante du plan de relèvement.

Pourquoi une restauration ne suffit pas toujours

Un WordPress “nettoyé” n’est pas forcément un WordPress “propagé”.

Après restauration, tout peut être parfait sur le serveur de fichiers et sur la base de données, mais les couches intermédiaires conservent parfois des versions en mémoire ou en stockage pendant une durée longue. On parle de cache côté navigateur, côté serveur, côté reverse proxy (selon l’hébergement), et côté CDN.

Un CDN, lui, est conçu pour accélérer. Il met en cache des contenus et les sert sans repasser par l’origine. Si le contenu infecté a été demandé au moment où il était accessible, le CDN peut avoir stocké la réponse. Ensuite, même si vous corrigez l’origine, le CDN continue d’honorer ce contenu en l’absence de purge.

Le problème est encore plus sournois quand l’infection ne touche pas tout le site. Certains chemins, certaines pages, certaines requêtes spécifiques peuvent être mises en cache. Vous restaurez proprement, mais vous testez uniquement la page d’accueil. La page d’accueil revient correcte, tandis que la redirection infectée reste visible sur une page interne. Résultat : vous “croyez” que tout va bien, jusqu’au moment où quelqu’un d’autre ouvre un autre lien.

J’ai déjà vu un cas où la restauration était correcte, mais un plugin d’optimisation avait mis en cache une version HTML compilée, et le CDN avait également gardé ces réponses. Les visiteurs “tombant” sur des pages mises en cache semblaient encore contaminés, alors que le code source sur l’origine était revenu à l’état sain.

Les couches de cache que vous devez avoir en tête

Sans entrer dans des architectures irréalistes, la réalité c’est que l’on rencontre souvent plusieurs systèmes en parallèle.

D’abord, le cache serveur et l’optimisation applicative : pages mises en cache, objets mis en cache, minification, compression, “lazy loading” rendu côté serveur, et parfois une gestion de cache au niveau du plugin. Ensuite, le cache au niveau du reverse proxy chez l’hébergeur. Certains environnements ont un layer de cache qui ne se synchronise pas instantanément avec les modifications de fichiers.

image

Puis il y a le CDN. Le CDN cache typiquement les réponses HTTP, souvent avec des TTL (durées de vie) qui peuvent aller de quelques minutes à plusieurs heures, parfois plus selon la configuration. Certains CDNs offrent des règles par chemin, par type de contenu, et peuvent aussi respecter des headers de cache que WordPress ou le plugin a envoyés.

Enfin, il y a la persistance côté navigateur. Même si tout est purgé au niveau CDN et serveur, un navigateur peut réutiliser une version ancienne. Là, on le remarque rapidement car un test en navigation privée donne une indication immédiate. Mais en investigation, si on veut conclure vite, on doit éviter de confondre un cache navigateur avec un cache CDN.

Signes qui orientent vers un cache CDN ou serveur

Vous n’avez pas besoin de “sentir” le problème, vous pouvez l’observer. Quelques indices fréquents :

    Les pages infectées disparaissent “d’un côté” mais reviennent “ailleurs”, comme si certains chemins étaient figés. Vous voyez encore des redirections ou des contenus injectés, mais le code sur l’origine est différent et propre. Les mêmes URLs ne réagissent pas de façon homogène : en test normal c’est infecté, en navigation privée c’est propre, ou l’inverse. Les logs réseau côté CDN montrent encore des réponses servies “depuis le cache” après restauration.

Ces observations ne prouvent pas à elles seules la cause, mais elles rendent la piste cache très crédible, ce qui justifie une purge structurée.

Choisir le bon moment pour purger

La purge n’est pas une action “au hasard”. Elle doit se placer dans une séquence qui limite le risque de servir un contenu incohérent, ou pire, de recacher un contenu infecté avant la fin du nettoyage.

L’approche la plus robuste suit généralement cette logique :

1) Terminer le nettoyage côté origine, y compris la suppression des fichiers malveillants, le remplacement des thèmes, plugins et WordPress core compromis, et la réinitialisation des éléments liés aux comptes (au minimum ceux qui ont été utilisés pendant l’attaque). 2) Vérifier que les pages critiques sont bien revenues, pas seulement une page, mais plusieurs types de ressources : HTML de pages, templates, éventuellement pages qui déclenchent du JavaScript ou des inclusions dynamiques. 3) Seulement ensuite, purger le cache applicatif et le CDN, puis confirmer avec des tests à plusieurs niveaux (navigation privée, requêtes depuis l’extérieur du réseau, et idéalement avec des outils qui permettent de voir l’origine servie).

Le moment exact dépend aussi de l’hébergement et des outils. Si vous purgez avant la fin du nettoyage, le CDN peut recacher une réponse infectée pendant une fenêtre courte mais réelle. Inversement, si vous attendez trop, vous prolongez l’exposition des visiteurs à du contenu incorrect.

En pratique, je vise une fenêtre courte : je nettoie, je revalide, je purge, je revalide à nouveau. Cela demande un peu de discipline, mais ça évite des discussions interminables du type “on a restauré, pourquoi c’est toujours infecté ?”.

Ce que la purge doit réellement couvrir

“Purger le cache” sonne comme une phrase unique, alors que les systèmes sont séparés.

Selon l’outil de cache utilisé, la purge peut s’exprimer en “purge de pages” (HTML), “purge d’objets” (requêtes ou fragments), et parfois “purge du minifié/concaténé”. Pour le CDN, il faut distinguer “purger tout” du “purgé par URL”, et vérifier si des règles de cache existent. Certaines configurations refusent de purger certaines catégories ou re-génèrent immédiatement.

Si vous avez des doutes, purger large est souvent plus sûr dans un contexte post-infection. Le coût, c’est une régénération plus lente et une charge accrue sur l’origine pendant quelques minutes. Mais c’est généralement acceptable, surtout la première fois après restauration.

Le compromis à décider est simple : pendant une infection, la priorité est la propreté et la cohérence. Sur un site critique, je préfère accepter un pic de trafic interne plutôt que laisser le CDN servir des réponses historiques.

Première étape : valider l’état “propre” côté origine

Avant de purger, j’aime vérifier la cohérence minimale. Pas besoin de tout auditer, mais il faut pouvoir répondre à une question de base : l’origine est-elle réellement revenue à un état qui ne génère plus le contenu malveillant ?

Concrètement, je teste :

    la page d’accueil et au moins une page interne une page de type article si le site en a une ressource statique qui dépend du HTML rendu (par exemple un JS inline ou un fichier chargé depuis le HTML) les pages qui contenaient la charge malveillante pendant l’incident, si on les connaît

Si les pages sont propres sur l’origine, la purge est beaucoup plus susceptible de résoudre le problème côté visiteurs. Si elles ne le sont pas, la purge n’est qu’un pansement qui masque le souci quelques minutes.

Checklist avant purge (origine prête)

    Confirmer que les fichiers WordPress, thèmes, plugins ont été remplacés quand nécessaire, et que les scripts injectés ont été supprimés. Vérifier les comptes administrateurs, utilisateurs à rôle élevé, et révoquer les sessions si l’outil le permet. Contrôler la génération des pages suspectes en navigation privée ou via une requête depuis un poste externe. S’assurer qu’aucun mécanisme de persistance connu n’est encore actif (cron malveillant, Webhooks, tâches planifiées, ou fichiers cachés).

Cette courte liste évite de purger un site qui est encore en train de redevenir propre.

Purger le cache WordPress et les optimisations applicatives

WordPress, même “standard”, peut cacher beaucoup de choses. Ajoutez un plugin de performance et vous multipliez les caches.

Selon l’outil, la purge peut être déclenchée via une interface d’administration (bouton “vider le cache”), via un cron qui purge à des horaires, ou automatiquement après mise à jour. Dans un scénario post-infection, je recommande d’aller au-delà de la purge “soft”. Videz explicitement les caches que vous contrôlez, même si cela déclenche une régénération.

Il faut aussi penser à deux réalités :

    Les pages peuvent être servies via un cache compilé qui tient à des paramètres. Par exemple, certaines variantes (langue, device, cookies) peuvent avoir des versions distinctes. Si vous purgez seulement “la page”, vous pourriez laisser une variante infectée. Les headers HTTP de cache influencent ce que le CDN va considérer. Si le serveur annonce un cache long, le CDN suivra.

Une fois que vous avez purgé le cache WordPress et celui de l’environnement applicatif, la prochaine étape est le CDN, car c’est lui qui maintient le problème visible pour une majorité de visiteurs.

Purger le CDN après restauration : la partie qui fait la différence

Purger un CDN après restauration, c’est comme changer la serrure, puis rappeler à tout le quartier que l’ancienne clé ne marche plus. Sans purge, certains “locataires” continuent d’ouvrir.

La méthode dépend du CDN. Les interfaces proposent souvent un bouton “Purge all”, et parfois une purge par URL. La purge par URL est pratique si vous savez exactement quelles pages ont été contaminées. Mais après une infection, on ne sait pas toujours tout ce qui a été mis en cache, surtout si l’attaque a injecté des contenus de manière dynamique.

Dans l’immédiat, je privilégie la purge la plus large https://gardewp.fr/nettoyage-malware-wordpress/ possible, parce qu’elle réduit le risque de laisser un chemin infecté encore accessible. Oui, cela génère un coût temporaire. Mais la régénération est généralement courte si l’infrastructure est correcte.

Ensuite, je surveille. Le CDN doit cesser de servir les anciennes réponses. On peut vérifier via :

    les en-têtes HTTP, en regardant si le CDN répond “from cache” ou “from origin” (selon l’outil) les logs du CDN et les requêtes en période de test la cohérence du contenu côté visiteurs, de préférence depuis deux réseaux différents

Checklist après restauration (cache et CDN)

    Vider le cache applicatif de WordPress et des plugins de performance, puis confirmer que le contenu régénéré est propre sur l’origine. Purger le CDN de manière large (purge de toutes les ressources ou au minimum des chemins concernés), pour éliminer les anciennes réponses injectées. Tester les URLs critiques depuis une navigation privée et depuis un réseau externe, pas seulement depuis votre machine habituelle. Surveiller les logs CDN et serveur pendant la première heure, pour détecter un éventuel rechargement de contenu suspect. Prévoir une règle de sécurité ou un durcissement avant de re-activer des options agressives de cache ou de minification.

Cette séquence vise un objectif précis : éviter que le cache ne “falsifie” votre validation.

Le cas particulier des URLs non évidentes

Une difficulté fréquente dans les infections WordPress, c’est que la charge peut ne pas se trouver dans les pages que vous regardez en premier. Elle peut apparaître dans :

    des pages archives (catégories, tags) des flux RSS des pages d’auteur des endpoints ou des requêtes spécifiques (selon la façon dont l’injection est réalisée)

Si votre test ne couvre pas ces zones, vous pouvez conclure trop vite que la restauration a tout réglé, puis subir des plaintes ultérieures.

Pour contourner ça, j’utilise généralement une méthode pragmatique : je cible les types de pages que le site sert vraiment. Pour un blog, ce sont les pages d’article, la liste d’articles, au moins une catégorie et le flux. Pour un site vitrine, ce sont les pages de conversion et tout ce qui charge des scripts ou des iframes.

Le CDN complique la donne, car il peut cacher ces réponses séparément. Donc la purge CDN doit être suffisante, ou bien vous devez purger au bon périmètre. Si vous n’êtes pas certain, purger large est l’option la plus sûre.

Pourquoi la purge peut “ne rien changer” (et ce que ça signifie)

Il arrive qu’après purge CDN et cache, le problème persiste. Dans ce cas, il faut accepter une réalité : le contenu affiché aux visiteurs n’est peut-être pas celui que vous pensez.

Voici les causes plausibles que j’ai rencontrées, sans prétendre à l’exhaustivité :

    Le serveur d’origine régénère encore du contenu malveillant. Le cache masquait le souci, et la purge révèle un problème encore actif. Un WAF ou un système de filtrage réécrit ou redirige des réponses selon des règles conservées. Les tests sont faits sur des URLs différentes, ou sur des variantes de cache (langue, paramètres, cookies) qui ne partagent pas le même cache. Le CDN n’a pas été purgé réellement, ou la purge a été faite sur un mauvais espace de configuration (par exemple si plusieurs zones existent, ou si le CDN utilise des clés de cache différentes).

Je conseille de ne pas interpréter trop vite. Si vous avez une infection confirmée, l’action la plus utile est de recoller les observations : HTML servi au navigateur, en-têtes de cache, chemins qui restent impactés, et comportement entre navigation privée et navigation normale.

Une purge sans amélioration, c’est un signal. Il faut le traiter comme une étape d’enquête, pas comme une simple opération technique.

Trade-offs : performance, régénération, et charge temporaire

Purger largement un CDN, ça a un prix. Les visiteurs peuvent avoir une latence légèrement supérieure au moment où le CDN regénère. Si votre origine est fragile, ce pic peut augmenter la charge.

Mais après une infection, ce trade-off est souvent acceptable. Vous gagnez de la cohérence, et surtout vous réduisez le risque de servir des contenus compromettants. Le coût de l’incertitude est bien plus élevé que le coût temporaire de quelques pages à régénérer.

Une autre contrainte est liée aux plugins de performance : certains n’aiment pas les purges fréquentes. Ils peuvent reconstruire de multiples variantes. D’où la recommandation de faire une purge “à un moment maîtrisé”, puis d’observer.

Si vous avez des scripts de minification ou de concaténation très coûteux, vous pouvez envisager de remettre en route ces options progressivement. Je le fais surtout quand l’origine est surchargée, ou quand l’équipe ne peut pas absorber une latence temporaire.

Après purge : revalider avant de “rassurer” tout le monde

Une fois la purge terminée, il faut revalider, sinon vous retombez dans le scénario classique “c’est bon sur moi”.

Le critère n’est pas seulement “ça ne redirige plus”. Je recommande d’observer la page finie, dans un navigateur réel, et de vérifier que les scripts externes et injections suspectes ont disparu. Selon l’attaque, l’indice peut être un bout de JavaScript ajouté, une balise modifiée, ou un chargement d’un fichier tiers non attendu.

Côté sécurité, la purge ne remplace pas les contrôles. Elle remplace le risque de servir des anciennes versions. Si le vecteur d’infection n’est pas neutralisé, le CDN ne fait que retarder l’échéance.

À ce stade, je réintroduis la logique de surveillance : vérifier les logs, surveiller les erreurs, et regarder si des accès inhabituels reviennent. Souvent, on voit aussi des tentatives répétées, qui expliquent pourquoi certains contenus “reviennent” alors même que vous avez purgé.

Un conseil de méthode : documenter ce que vous purge

Ça semble trivial, mais après un incident, la mémoire se brouille vite. Notez ce que vous avez purgé, quand, et sur quelle portée.

Pour le CDN, notez le type de purge : “all” ou par chemin, l’heure approximative, et l’identifiant de configuration si vous en avez plusieurs. Pour WordPress, notez quel cache a été purgé, et si des options agressives ont été désactivées puis réactivées.

image

Ce journal aide quand un collègue arrive et voit encore une page suspecte. Vous pouvez comparer l’URL, le moment, et les en-têtes observés. Vous évitez de repartir dans une purge complète alors que la cause est ailleurs, par exemple dans une variante de cache ou dans un chemin non couvert.

Pièges fréquents à éviter

Sans faire une liste interminable, il y a quelques erreurs qui reviennent.

La première est de purger le cache WordPress sans purger le CDN, ou de faire l’inverse. Dans un environnement où le CDN cache réellement, une purge partielle n’apporte qu’une correction partielle.

La deuxième est de ne tester que depuis un environnement déjà “nettoyé” côté navigateur. Le navigateur privé est utile, mais il ne remplace pas un test depuis l’extérieur et une lecture des en-têtes.

La troisième est de se dire que “la sauvegarde est propre donc c’est bon”, sans vérifier que la sauvegarde n’inclut pas un mécanisme de persistance, ou sans vérifier que la restauration n’a pas été partielle (par exemple certains répertoires ou certains fichiers de configuration exclus par le backup).

Le quatrième piège concerne le timing. Une purge trop tôt peut aider des visiteurs à voir une page encore instable, et une purge trop tard maintient l’exposition.

Toutes ces erreurs ont un point commun : elles traitent la purge comme une action isolée, alors qu’elle dépend de la préparation en amont et de la validation juste après.

Si vous devez agir vite : stratégie pratique sur 30 à 90 minutes

Quand l’urgence est réelle, vous voulez une séquence qui “réduit” le risque le plus vite possible. L’ordre logique que je recommande dans ce type de crise reste celui-ci : nettoyage et validation minimale sur l’origine, purge de WordPress, purge CDN large, puis revalidation avec plusieurs tests.

Dans les faits, vous pouvez rencontrer des cas où la régénération du contenu prend quelques minutes. C’est normal. Le but est de voir l’évolution : d’abord les pages critiques, ensuite les pages secondaires, et enfin les chemins moins évidents (flux, archives, auteur).

Si au bout d’un laps de temps raisonnable (souvent une dizaine de minutes à une heure selon la complexité et la charge), certains éléments restent infectés, le problème est plus profond que le cache. Vous revenez alors à l’investigation sur le vecteur.

Le message important est simple : la purge après restauration règle le cache, pas la cause de l’infection. Mais elle est indispensable pour que les visiteurs ne reçoivent plus le passé.

Conclusion implicite, mais indispensable : purge = partie du nettoyage

Quand on traite un site WordPress infecté, la purge du cache et du CDN après restauration ne doit pas être considérée comme un “détail technique”. C’est souvent ce qui détermine si vos efforts de nettoyage deviennent visibles chez les visiteurs, ou s’ils restent invisibles au public parce que le CDN continue d’entériner l’ancienne version.

Le plus efficace, c’est une approche disciplinée : préparer l’origine propre, purger dans le bon ordre, puis revalider. Cette méthode évite les faux retours positifs et limite le temps pendant lequel des pages compromises peuvent encore circuler, même après une restauration correcte.