Désinfection WordPress : nettoyer le footer et les en-têtes compromis
Quand un site WordPress se fait compromettre, ce n’est presque jamais “tout ou rien”. La plupart du temps, l’attaque est discrète, elle se glisse dans des endroits qui semblent anodins. Et parmi les zones les plus ciblées, il y a deux classiques: le footer et les en-têtes https://gardewp.fr/ https://gardewp.fr/ (headers) renvoyés par le serveur ou injectés dans les pages.
Le résultat peut prendre plusieurs formes: redirections vers des pages douteuses, affichage d’un script de tracking non autorisé, chargement de ressources externes au moment où la page se termine, ou encore modification des entêtes pour détourner la sécurité. Le pire, c’est que ces modifications peuvent rester invisibles à l’oeil, surtout si elles s’activent pour certains navigateurs, certaines langues, ou certains cookies.
Ce guide est écrit pour une désinfection pratique, orientée terrain. Je détaille les scénarios fréquents, ce qu’il faut vérifier en priorité, comment nettoyer sans casser le thème, et comment confirmer que le site ne réinjecte plus quoi que ce soit.
Pourquoi footer et en-têtes sont des cibles “logiques”
Le footer est un endroit idéal pour l’attaque. D’une part, il est présent sur presque toutes les pages, puisqu’il vit dans le fichier d’assemblage du thème. D’autre part, les visiteurs voient souvent le contenu avant la fin, ce qui laisse à l’injection le temps de passer sous les radars. Beaucoup de scripts malveillants sont placés tout en bas, parfois avec des balises HTML qui ressemblent à du “marketing”, du chat, ou de l’optimisation.
Les en-têtes, eux, agissent plus “technique”. Une injection au niveau HTTP peut:
réduire l’efficacité des mécanismes de protection, ajouter des politiques incohérentes, ou servir de déclencheur conditionnel à des scripts côté navigateur.
Selon votre configuration (serveur, CDN, WAF, reverse proxy), les en-têtes peuvent venir de plusieurs couches: Nginx ou Apache, FastCGI, WordPress via l’envoi de réponses, ou un plugin qui ajoute des headers à la volée.
Quand vous repérez un footer ou des en-têtes compromis, vous avez deux problèmes à résoudre en même temps: supprimer la source de l’injection, et empêcher toute réactivation.
Premier réflexe: déterminer le “point d’injection” exact
Avant de toucher au code, je recommande de cerner où se fait réellement l’injection. Sur un site WordPress compromis, il y a trois lectures possibles du problème.
D’abord, vous pouvez avoir une modification statique dans un fichier: par exemple, le thème modifié, un plugin corrompu, ou un fichier ajouté dans le répertoire. Dans ce cas, le contenu injecté est présent à chaque requête, et vous retrouverez des traces dans les fichiers.
Ensuite, l’injection peut être dynamique: un script ou un plugin s’exécute à la demande et insère du contenu dans le footer à partir de conditions. Dans ce cas, le code suspect peut sembler “propre” à première vue, et l’injection se produit uniquement sous certains critères.
Enfin, il existe l’injection au niveau serveur ou proxy, parfois via des règles modifiées (Nginx, .htaccess), ou via un CDN qui ajoute ou remplace du contenu. Elle ne dépend pas de WordPress au sens strict, même si l’impact se voit dans le HTML final.
Une façon simple de trancher consiste à regarder le HTML et les headers sur plusieurs pages, puis à comparer avec un environnement sain. Si vous ne disposez pas d’un miroir, comparez au moins entre:
une page publique et une page d’administration (quand elle existe), la page d’accueil et une page “à gabarit” différent, le site en HTTP et en HTTPS, et avec ou sans paramètres (comme un paramètre de recherche).
L’objectif est de repérer si l’injection touche un seul type de template, ou si elle se produit partout.
Observer le footer sans se faire piéger par “ce que vous croyez voir”
Le footer compromis peut se manifester de trois manières qui se confondent souvent.
La première, c’est un code visible dans le HTML: scripts, balises iframe, URLs externes, ou commentaires HTML qui indiquent une charge utile. La deuxième, c’est une injection “minifiée” qui ressemble à une fonctionnalité du site, mais pointe vers un domaine non attendu. La troisième, plus vicieuse, c’est un comportement côté navigateur déclenché par des variables (cookies, user-agent, langue) ou par l’ordre de chargement.
Pour analyser proprement, je fais souvent ces vérifications:
ouvrir l’onglet “réseau” et repérer les requêtes externes déclenchées juste avant que la page se termine, inspecter le DOM à la fin du chargement pour voir quel script ajoute quoi, et comparer l’ordre de chargement des ressources (surtout si vous utilisez un cache agressif ou un minifier côté thème).
Si vous voyez un script injecté dans le footer, essayez de remonter sa source logique. Parfois le script n’est pas dans le fichier footer lui-même, mais dans un fichier inclus plus haut, qui s’attache ensuite au moment où le footer “est rendu”.
En-têtes compromis: regarder au bon niveau, pas seulement dans Chrome
Sur WordPress, beaucoup pensent “je vois des headers bizarres dans l’inspecteur, donc WordPress est le coupable”. Ça peut être vrai, mais pas toujours. Une configuration d’hébergement peut injecter des en-têtes, et un plugin peut modifier des en-têtes à l’exécution.
Je vous propose de distinguer deux choses: les headers “de sécurité” (qui encadrent le navigateur) et les headers “de diagnostic” (qui indiquent le passage par une couche intermédiaire).
Un coup typique consiste à injecter une Content-Security-Policy trop permissive ou à jouer sur des headers qui permettent d’exécuter du contenu non souhaité. Un autre consiste à ajouter des headers qui servent juste à déclencher un comportement côté client, par exemple via certains scripts qui lisent la réponse.
La bonne approche est de consulter:
les headers HTTP bruts (via un outil de type curl ou équivalent), et aussi ceux renvoyés réellement au navigateur, car un CDN peut modifier le comportement.
Si votre site est derrière Cloudflare, Fastly, Akamai ou équivalent, vérifiez la configuration du proxy, surtout si vous avez l’habitude d’ajouter des règles de sécurité. Une compromission peut viser aussi le panneau de configuration, ou un bot qui teste des failles faibles.
Nettoyer sans casser: préparer la désinfection comme un chantier
Avant de supprimer quoi que ce soit, sécurisez le terrain. Une désinfection réussie n’est pas uniquement “enlever du code”, c’est aussi éviter de détruire votre site au passage.
Concrètement, j’installe un mode de travail qui respecte trois objectifs: couper la propagation, préserver vos données, et garder une trace.
couper les accès au site si vous constatez une redirection active, sauvegarder les fichiers et la base de données, puis travailler sur une copie (staging ou environnement isolé).
Il y a une nuance importante: si le site injecte du contenu à partir d’un script qui se propage via des requêtes, vous pouvez vouloir limiter la propagation avant toute analyse. Par ailleurs, si vous effacez immédiatement les fichiers sans sauvegarder, vous perdez la possibilité de comprendre la source de l’injection.
Identifier la source: thèmes, plugins et fichiers d’injection
Sur un site compromis, la recherche de “code suspect” peut vite devenir une chasse au dragon. Le but n’est pas de tout lire à la main, c’est de trouver la logique de l’injection.
Le point de départ est le footer et les inclusions de thème. Le footer est rendu via un fichier de thème typique, puis le contenu est parfois complété par des fonctions et hooks. Un plugin peut s’accrocher à un hook WordPress pour imprimer du HTML à la fin, ou à un hook d’initialisation.
Je cherche souvent des signaux simples:
présence d’un fichier avec un nom “banal” mais récent, pas dans votre pratique de déploiement, ajout de fonctions qui appellent des URL externes, présence de chaînes inhabituelles, parfois encodées (base64) ou chiffrées, code qui utilise des fonctions d’exécution, d’écriture, ou de téléchargement à partir d’une URL.
Un cas très courant: un fichier PHP modifié dans le thème ou un plugin “écrasé” par l’attaque. Parfois, le code malveillant est ajouté à la fin d’un fichier existant, ce qui rend la modification difficile à repérer sans diff.
La méthode que je préfère consiste à comparer vos fichiers actuels avec une copie connue (version saine du thème, version saine des plugins, ou au minimum une version stockée lors d’un déploiement antérieur). Si vous n’avez pas de version saine, vous pouvez utiliser des checksums, ou réinstaller proprement le thème et les plugins, mais en gardant au moins les traces des différences.
La checklist qui évite les erreurs classiques
Voici une liste courte, orientée “ne pas rater la source” et “ne pas casser votre site”.
Identifier le contenu injecté dans le footer, puis remonter l’origine (thème, hook, plugin, fichier inclus) Inspecter les en-têtes HTTP renvoyés, puis vérifier si un proxy (CDN, reverse proxy) intervient Désactiver les plugins non essentiels en premier, puis tester le rendu des pages problématiques Remplacer le thème et les plugins par des versions propres, tout en conservant une copie des fichiers modifiés pour analyse
Ce que j’aime dans cette approche, c’est qu’elle réduit le temps de réflexion. Vous évitez de nettoyer à l’aveugle un footer alors que l’injection vient d’un hook dans un plugin.
Cas fréquent 1: footer injecté via un fichier du thème
Quand le problème semble venir du footer, commencez par la cohérence du thème.
Je regarde d’abord:
si le fichier footer.php contient du code que vous n’avez jamais ajouté, si la structure du footer correspond à votre thème d’origine, si une fonction additionnelle est introduite pour imprimer du script.
Beaucoup de thèmes ont un footer qui inclut des scripts enregistrés via wpenqueuescript. Si vous voyez au contraire un script directement injecté avec des balises inline, c’est un drapeau rouge, sauf si vous utilisez explicitement un mécanisme prévu.
Ensuite, inspectez le code des inclusions autour du footer. Par exemple, certains thèmes impriment du HTML dans header.php et complètent au footer. Un attaquant peut déposer du code dans header.php qui prépare une variable, puis un script plus tard s’exécute au footer.
Dans ce cas, nettoyer uniquement footer.php ne suffit pas. Vous devez suivre la chaîne: d’où vient la variable ou la logique, puis où elle est utilisée.
Cas fréquent 2: footer injecté via un plugin qui “print” du HTML
Un plugin malveillant peut ne jamais toucher au footer.php. Il peut se contenter d’utiliser un hook du type wp_footer ou d’autres actions équivalentes. Du point de vue visuel, vous aurez une injection “dans le footer”, mais la source réelle est ailleurs.
Quand je suspecte un plugin, je fais un test simple en staging si possible: désactiver un à un les plugins, en priorité ceux qui:
gèrent des publicités, ajoutent des scripts externes, manipulent le HTML, modifient les en-têtes.
S’il y a peu de plugins, le tri est rapide. S’il y en a beaucoup, je regarde d’abord ceux qui ont des contributions récentes ou ceux qui ont des fichiers très modifiés. WordPress laisse parfois des indices dans les dates de modification.
Une prudence: désactiver des plugins peut casser des fonctionnalités légitimes. C’est pour cela que je préfère un environnement de test.
Cas fréquent 3: injection conditionnelle selon cookies, origine, ou langue
Les attaques modernes sont souvent conditionnelles. Vous pouvez constater un footer “normal” sur un navigateur, puis un footer compromis sur un autre, ou selon l’URL.
Si vous observez ce comportement, refusez la tentation de “nettoyer au hasard”. Faites plutôt un relevé:
quel navigateur, quel pays ou langue, quel chemin d’URL, si le site renvoie un script seulement après un événement (clic, hover) ou juste après le chargement.
Le code conditionnel peut être caché dans un plugin, ou dans un fichier du thème, mais il s’appuie sur des variables côté serveur comme la langue, ou sur des informations HTTP côté requête.
Ici, la stratégie qui marche le mieux est de partir de la requête infectée que vous observez. Vous comparez ensuite le HTML brut de la page “infectée” et de la page “saine” (ou moins infectée). Les différences de code se réduisent, et vous pouvez retrouver plus facilement la branche conditionnelle.
Vérifier les en-têtes: ce que “corriger” veut vraiment dire
Nettoyer les en-têtes compromis ne consiste pas forcément à supprimer un header. Parfois le header est légitime, et c’est la configuration ailleurs qui est mauvaise.
Je vois souvent des cas où:
un plugin ajoute des en-têtes de sécurité, mais le fait de manière incorrecte, ou bien une règle de serveur a été modifiée pour contourner une limitation.
Le travail propre consiste à retrouver qui ajoute quoi. WordPress peut envoyer des en-têtes, mais il faut vérifier les hooks et les fonctions de “output”. Si vous trouvez une fonction qui appelle header(…) Ou qui manipule des en-têtes à partir de données externes, vous avez une piste.
Si vous ne trouvez rien côté WordPress, regardez la couche serveur ou CDN. Un simple fichier de configuration modifié peut injecter des en-têtes.
Une fois la source trouvée, le remède dépend de l’intention:
si le header a été ajouté par un module légitime, réinstallez le module ou corrigez la version, si le header est malveillant ou incohérent, supprimez la logique, puis testez.
Le point de contrôle final n’est pas “ça ressemble à avant”. C’est la validation en double: via headers HTTP bruts, et via comportement réel du navigateur (par exemple s’il y a des scripts qui ne se chargent plus).
Réinstallation propre: thème, plugins et fichiers “à risque”
Quand un site a été compromis, l’option la plus robuste est souvent de réinstaller proprement le thème et les plugins, plutôt que de corriger à la main des morceaux épars.
Cela ne veut pas dire “supprimer et prier”. Le bon compromis, c’est:
récupérer une version saine du thème, récupérer les versions saines des plugins, remplacer les fichiers, puis remettre uniquement les fichiers personnalisés que vous pouvez justifier.
Le risque d’une correction manuelle est de rater une branche ou un fichier ajouté qui réactive l’injection. La réinstallation réduit ce risque, à condition de traiter le problème de manière cohérente.
Si vous avez des modifications personnalisées dans le thème, documentez-les avant remplacement. Ensuite, transférez uniquement ce qui est légitime et gardez un diff.
Une déviation fréquente: le footer “revient” après le nettoyage
Si, après nettoyage, vous observez que le footer redevient compromis quelques heures plus tard, il y a presque toujours un mécanisme de réactivation.
Les causes typiques:
un fichier malveillant encore présent dans un répertoire non remplacé, un nouvel upload automatisé, une tâche planifiée (cron) qui dépose du code, une sauvegarde ou un outil de déploiement compromis (par exemple un script d’automatisation qui réimporte un thème infecté).
C’est pour ça que je recommande de vérifier aussi:
les tâches planifiées WordPress, les fichiers du dossier wp-content (pas seulement le thème), les droits et les comptes utilisateurs.
Sur les sites compromis, l’attaque vise parfois le long terme: elle laisse un “mécanisme de maintenance” qui réécrit le footer à chaque cycle.
Compromission: traiter les utilisateurs et les accès
Un footer et des en-têtes compromis sont des symptômes. La cause peut être un compte utilisateur, un rôle trop permissif, ou une élévation de privilèges.
Après nettoyage, je vérifie toujours:
la liste des utilisateurs existants, les dates de création, les rôles (administrateur, éditeur), et les changements de mots de passe.
Si un compte a été créé à votre insu, vous devez le supprimer (ou le désactiver), puis changer les mots de passe des comptes restants. Vous devez aussi vérifier les connexions récentes si vous avez des logs disponibles.
C’est également là que l’authentification à deux facteurs (quand possible) aide énormément, non pas comme gadget, mais comme barrière réaliste.
Signaux d’alarme simples (et utiles) à repérer dans le code
Pour ne pas vous noyer dans du minifié ou du base64, je m’appuie sur des signaux qui reviennent très souvent. Voici une petite liste de repères, sans prétendre que tout est certain, mais suffisamment pour orienter vos recherches.
Fonctions PHP qui téléchargent ou écrivent des fichiers, ou qui appellent des URL externes depuis le contexte d’affichage Scripts JavaScript chargés depuis des domaines inconnus, surtout ajoutés inline dans les gabarits Utilisation de code encodé ou masqué, puis décodage au moment de l’exécution Hooks WordPress qui impriment du HTML à la fin sans raison fonctionnelle claire Modifications récurrentes après remplacement, signe d’un mécanisme de réactivation
Quand vous voyez plusieurs de ces signaux ensemble, l’hypothèse “infection” devient solide. Et vous pouvez travailler plus vite.
Tests de validation: prouver que la désinfection tient
Une désinfection sérieuse ne se valide pas une fois. Elle se valide dans le temps et sous plusieurs angles.
Je fais en général trois couches de vérification: 1) le rendu du footer sur plusieurs pages, 2) la vérification des en-têtes HTTP bruts, 3) et un test de comportement côté navigateur, en particulier sur les ressources externes.
Si vous avez un système de cache (plugin, cache serveur, CDN), attendez le bon scénario. Un cache peut afficher une version “ancienne” après nettoyage, ce qui donne une fausse impression de succès. Je purge proprement les caches au bon niveau, puis je teste.
Ensuite, je surveille pendant quelques heures à une journée. Si l’injection revient, il faut reprendre la chasse depuis la source probable de réécriture.
Durcir après nettoyage: éviter que le footer et les en-têtes ne soient à nouveau la cible
Durer est plus difficile que supprimer. Après une désinfection, vous voulez rendre l’attaque plus coûteuse, et détectable.
Les actions efficaces que j’ai le plus vues fonctionner:
réduire les plugins et thèmes actifs aux seuls nécessaires, mettre à jour régulièrement thèmes et plugins, retirer les extensions inutiles qui modifient des en-têtes ou injectent du script, limiter les droits d’écriture sur les fichiers, et surveiller les changements de fichiers dans wp-content.
Si votre hébergement le permet, contrôlez les permissions et l’intégrité. Et côté WordPress, gardez une hygiène stricte sur les comptes.
Il y a aussi une approche pragmatique: loguer. Les logs (serveur, WordPress, et éventuellement WAF ou CDN) donnent des indices si quelque chose se réactive. Ce n’est pas glamour, mais ça fait gagner des heures au moment où vous en avez besoin.
Exemple concret de diagnostic (sans magie)
Sur un site client, le symptôme était un footer qui chargeait une ressource externe juste après le chargement. Au début, le réflexe était de modifier footer.php. Mais le contenu suspect ne correspondait à aucun script “connu” et apparaissait aussi sur des pages où footer.php n’était pas directement différent, ce qui suggérait un hook.
Le diagnostic s’est affiné en comparant le HTML source entre une session “propre” et une session “infectée”. L’injection était déclenchée par une condition liée à l’agent utilisateur. En inspectant les hooks, l’élément déclencheur ne venait pas du footer.php, mais d’un plugin léger, installé depuis peu et peu utilisé.
Une fois le plugin réinstallé et les fichiers “additionnels” supprimés, le footer est redevenu normal. Le point crucial a été de vérifier aussi les en-têtes, car le plugin modifiait une politique qui permettait le chargement du script injecté. Sans cela, le navigateur continuait de laisser passer du contenu même après nettoyage partiel.
Cette histoire ressemble à beaucoup d’autres. Elle illustre un principe: si vous nettoyez le symptôme sans traiter la mécanique d’injection, vous payez la facture plus tard.
Ce qu’il faut retenir quand footer et en-têtes sont compromis
Quand WordPress montre des signes de compromission dans le footer et les en-têtes, pensez “chaîne complète”, pas “fichier unique”.
Le footer est l’endroit où l’effet se voit, les en-têtes sont l’endroit où le comportement peut être orchestré, et la source est souvent un mélange: thème modifié, plugin qui s’accroche à un hook, ou couche serveur. Le succès vient de votre capacité à remonter depuis l’observation vers la logique, puis à valider sur plusieurs pages et plusieurs couches.
Si vous devez vous concentrer sur une seule idée: ne partez pas du code que vous voyez pour tout résoudre, partez de la mécanique d’injection que vous observez, puis remontez jusqu’à la première source modifiée. C’est ce qui évite les “nettoyages qui reviennent” et qui rend la désinfection durable.