Quand un site WordPress est infecté, ce n’est pas seulement une question de “sécurité”. Très vite, on touche à la confiance, au SEO, et à la confiance des utilisateurs. Les injections dans les pages sont l’un des scénarios les plus pénibles, parce qu’elles se voient, qu’elles peuvent changer selon la page ou même selon l’utilisateur, et qu’elles donnent l’impression que “ça revient toujours”.
Le cas typique ressemble à ceci. Vous ouvrez une page, tout paraît normal, puis vous remarquez une ligne de script qui ne devrait pas être là, un appel réseau vers un domaine étrange, ou une iframe invisible qui charge un contenu. Parfois, c’est uniquement sur certaines URLs, ou uniquement quand on consulte depuis mobile, ou quand on est connecté. Ces détails comptent énormément, parce qu’ils orientent vers le bon endroit où l’injection est logée.
Dans ce billet, je veux parler concrètement du traitement quand l’infection se manifeste par des injections dans les pages WordPress, avec une méthode qui évite de “tout réinstaller pour rien” et, surtout, qui réduit le risque de récidive.
Comprendre ce qu’on appelle “injection dans une page” sur WordPress
Sur WordPress, le rendu HTML d’une page vient de plusieurs couches. Le navigateur reçoit un mélange de contenu, de modèle de thème (fichiers PHP), de données issues de la base (contenu des articles, options, métadonnées), et parfois de fragments injectés par des plugins, des shortcodes, des widgets, ou des hooks.
Une injection “dans les pages” peut donc être :
- une modification d’un fichier de thème ou de plugin (un hook qui ajoute du JavaScript malveillant à la sortie du contenu) une donnée corrompue en base (un champ dans les options, un contenu d’article, une page en particulier) une altération via un shortcode ou un champ “custom” (un bloc réutilisable, du HTML personnalisé) une insertion conditionnelle (par exemple selon l’agent utilisateur, la langue, le pays, ou si le visiteur suit un paramètre)
La nuance est capitale. Si vous nettoyez uniquement la base alors que la porte d’entrée est dans un fichier, vous perdrez du temps. À l’inverse, si vous corrigez uniquement les fichiers alors que la charge utile est dans la base, elle reviendra au prochain rendu.
J’ai vu des sites où la page semblait “injectée” de façon visuelle, mais où la vraie cause était un champ dans les options WordPress, modifié après un accès administrateur compromis. Le script ne venait pas d’un fichier téme, il apparaissait parce que la sortie du thème consommait cette option.
Les signaux qui orientent rapidement votre diagnostic
Avant de toucher à quoi que ce soit, prenez quelques minutes pour observer. Sur un site WordPress infecté, les symptômes peuvent être trompeurs, mais certains indices sont très parlants.
Regardez notamment :
- Le code injecté est-il dans le , juste avant la balise de fin , ou au milieu du contenu ? Le domaine ou l’URL appelée contient-il des mots clés, des chiffres répétitifs, ou des sous-domaines randomisés ? La page “saine” au sens visuel renvoie-t-elle pourtant un HTML modifié ? L’injection apparaît-elle uniquement sur les pages publiques, ou aussi dans l’éditeur ? Est-ce que l’effet change selon la session (vous connecté en admin, ou non) ?
Le point le plus pratique, c’est de comparer deux pages : une qui semble infectée et une qui ne l’est pas. Si une seule page est touchée, je pense d’abord à la base (contenu, meta, champ de page builder, option liée à ce template). Si toutes les pages publiques portent la même charge, je pense davantage à un mécanisme global dans le thème, un plugin, ou des hooks.
Ne pas paniquer : la séquence de travail qui évite les erreurs
Le piège classique, c’est de réinstaller “à l’arrache” dès qu’on voit un script. On remplace des fichiers, on met à jour WordPress, puis on constate que l’injection revient au prochain crawl. Résultat : on a perdu la piste et, parfois, on a supprimé le contexte qui aurait permis d’identifier la porte d’entrée.
Voici une approche qui marche bien en atelier, quand on traite un site WordPress infecté, et spécifiquement quand l’injection se voit dans les pages.
Étape 1 : isoler et documenter ce qui change
Avant tout nettoyage, capturez.
Vous pouvez faire simple : ouvrez la page avec un inspecteur réseau et vérifiez l’existence d’une requête vers un domaine suspect. Prenez aussi une capture du HTML tel qu’il est réellement renvoyé au visiteur. Le but n’est pas de “piéger” l’attaquant, c’est de conserver un repère stable.
Je conseille aussi d’ouvrir la page en session privée (sans cookies). Si l’injection existe en session privée et disparaît quand vous êtes connecté, vous avez un indice fort sur une logique conditionnelle.
À ce stade, notez aussi l’URL exacte de la page, le type de page (article, page statique, archive), et le comportement observé.
Étape 2 : vérifier l’intégrité du “cœur” et des thèmes
Sur WordPress, la première vérification utile n’est pas d’aller chercher “quel fichier contient le script”, c’est de vérifier si vous avez des fichiers modifiés par rapport à une installation saine.
Si vous utilisez un thème custom, ou si vous avez des modifications légitimes, vous devez garder votre copie de référence. Sinon, vous pouvez comparer avec une version propre, par exemple en téléchargeant WordPress et en comparant les dossiers wp-admin, wp-includes et la racine.
Ensuite, regardez le thème : certains compromis sont assez simples à détecter, comme des ajouts de code dans un fichier functions.php, dans un template comme page.php, ou dans des fichiers plus inattendus comme un fichier “include” ou un utilitaire chargé en amont.
À ce niveau, je cherche surtout des patterns : eval(, base64_decode(, des “générateurs” de chaînes, des accès réseau via curl ou file_get_contents vers des domaines externes, ou des fonctions qui ne correspondent pas au thème.
Étape 3 : chercher la charge utile dans la base
Quand l’injection se fait “dans les pages”, la base peut être la source réelle. On voit souvent des entrées modifiées dans :
- le contenu des pages ou articles les champs des builders (selon le constructeur, cela peut être du HTML stocké dans une métabox) les options et meta liées à un plugin des shortcodes et des contenus réutilisables
Un signal fréquent : la charge utile est présente dans le HTML rendu, mais elle ne se trouve nulle part dans les fichiers PHP du thème, parce que le thème affiche un champ stocké en base.
Ici, ce qui vous aide, ce sont les recherches sur des fragments du code injecté. Si vous repérez un bout de script, cherchez ce bout dans la base (ou approchez avec un domaine suspect). C’est bien plus efficace que de passer votre temps à parcourir des milliers de lignes d’options à la main.
Étape 4 : trouver la porte d’entrée (le vrai enjeu)
Nettoyer la charge utile, c’est important. Mais si vous ne trouvez pas la porte d’entrée, vous aurez une récidive.

La porte d’entrée peut être :
- un compte admin compromis une vulnérabilité de plugin des mots de passe réutilisés une mauvaise configuration exposant l’installation une écriture de fichiers via permissions trop larges un thème enfant ou un plugin custom modifié
Dans un cas que j’ai traité, l’injection venait d’un plugin qui semblait “normal” en surface, mais qui avait une ligne conditionnelle cachée dans un fichier chargé uniquement quand une option spécifique était activée. Tant que l’option n’était pas nettoyée, le code revenait même après suppression et réinstallation du plugin. Le diagnostic a été rendu possible en comparant le HTML rendu avant et après suppression des options.
Un mini-check avant de “remonter” un site propre
- Vérifiez si le script injecté est présent en session privée et/ou quand vous êtes connecté Comparez une page infectée et une page saine, même template si possible Cherchez un fragment unique de la charge utile dans les fichiers et dans la base Identifiez la logique conditionnelle (agent utilisateur, cookies, paramètres, langue)
Ce mini-check évite d’aller dans le mauvais sens.
Où l’injection est le plus souvent cachée
Sans faire une liste exhaustive, restaurer fichiers WordPress propres il y a des endroits récurrents. Le but ici, c’est de vous faire gagner du temps, pas de vous faire perdre dans des hypothèses.
Si vous voyez un script dans le sur beaucoup d’URLs, je pense en priorité à un hook global, souvent dans un fichier de thème ou un plugin. Si vous voyez l’injection “au corps de page”, juste après le contenu principal, c’est parfois un filtre appliqué sur le contenu, ou une fonction qui altère le rendu du contenu.
Voici les zones que j’inspecte en premier quand on me dit “l’injection est dans les pages” :
- dans les thèmes, notamment functions.php et les fichiers utilisés par le template de page dans les plugins “invisibles” ou peu utilisés, y compris ceux désactivés mais pas supprimés dans la base, surtout options et métadonnées liées au builder ou au type de page
La logique est simple : plus l’injection est large et constante, plus vous cherchez un mécanisme global. Plus elle est ciblée sur quelques pages, plus vous fouillez la base et les champs spécifiques.
Méthode de nettoyage quand le code est dans le rendu HTML
Une fois le diagnostic clair, le nettoyage ressemble à une succession de décisions. Il faut être rigoureux, parce que certains “correctifs” bricolés finissent par rendre le site instable.
Nettoyer la charge utile sans casser la page
Si le script injecté est dans un fichier PHP du thème ou du plugin, la correction est souvent directe : restauration du fichier à partir d’une version saine, puis suppression du code malveillant. Selon la complexité, une mise à jour du thème ou d’un plugin peut remettre les bons fichiers, mais attention : si vous avez un thème custom, une mise à jour peut écraser vos modifications légitimes. D’où l’intérêt de sauvegarder au préalable et de documenter les changements.
Si la charge utile est dans la base, la suppression demande prudence. Retirer le mauvais contenu dans une page spécifique peut être simple. Mais si le champ injecte des éléments au rendu via un champ “global” (option) ou un shortcode, vous devez nettoyer le bon endroit.
Astuce pratique : avant de supprimer, copiez le contenu de l’option ou du champ corrompu. Au minimum, conservez un export. Cela vous permet de revenir en arrière si vous supprimez un élément légitime par erreur.
Restaurer sans réinfection
Une fois la charge utile enlevée, je fais un cycle de test. Je mets à jour le site vers l’état stable (même version si vous ne pouvez pas monter tout de suite), je désactive temporairement les plugins non essentiels, puis je teste l’affichage de quelques pages clés, en session privée et côté admin.
Le but est de déterminer si l’injection dépend d’un plugin précis ou si c’est un mécanisme global.
Si vous désactivez un plugin et que l’injection disparaît, vous avez gagné un morceau du puzzle. Ensuite, vous pouvez réinstaller proprement le plugin à partir d’une source fiable, ou remplacer par une alternative.
Corriger la cause, pas seulement le symptôme
Le plus dur, c’est quand tout a l’air “propre” mais que l’injection revient après un délai. Là, l’attaquant a souvent mis en place une persistance.
Sur WordPress, la persistance peut être :
- un fichier modifié dans un dossier chargé à la demande une tâche planifiée (WP-Cron modifiée) un utilisateur nouvellement créé avec un rôle élevé un plugin réinjectant du code via une logique interne
Je recommande de vérifier ces points, même si vous avez déjà supprimé le script visible. Certains mécanismes sont discrets.
Vérifications qui changent souvent le verdict
Sans entrer dans une liste longue, je vérifie systématiquement quatre choses lors d’un traitement d’infection par injection.
Je commence par la liste des comptes et la date de création des utilisateurs. Un compte créé récemment est un signal fort. Ensuite, je vérifie l’état des plugins et thèmes : présence d’un plugin non listé “normalement”, dossiers ajoutés, fichiers modifiés. Puis je fais une passe sur la planification WordPress si vous avez l’impression que le contenu revient après un certain temps. Enfin, je regarde les logs d’accès quand c’est possible, même si ce n’est pas toujours “propre” selon votre hébergeur.
Si votre hébergeur le permet, vous pouvez aussi consulter les logs PHP pour repérer des erreurs qui arrivent juste avant la réinjection. L’injection peut être déclenchée par un chemin spécifique, comme un endpoint particulier.
Réduire la surface : mise à jour et durcissement réalistes
Une fois le nettoyage terminé, la partie “prévention” compte autant que la suppression du code. Mais elle doit rester réaliste. Sur des sites en production, trop de verrouillage peut casser des intégrations, ou bloquer un robot d’indexation légitime.
Je vise un équilibre : corriger rapidement les points de vulnérabilité connus, puis durcir sans casser.
Quelques mesures qui sont généralement pertinentes après une infection par injection :
- mettre à jour WordPress, thèmes et plugins vers des versions à jour supprimer les plugins et thèmes inutilisés modifier tous les mots de passe, y compris ceux des comptes qui ont accès à la base et à l’hébergement vérifier les permissions de fichiers, et corriger celles qui sont trop ouvertes activer une sécurité applicative côté hébergeur si elle existe déjà (WAF, règles de filtrage)
Le détail qui fait gagner du temps : si vous modifiez seulement les mots de passe WordPress mais que le compte FTP ou SSH du fournisseur est compromis, vous ne faites que déplacer le problème. J’ai déjà vu un cas où le site “reprenait” le même comportement après correction, simplement parce que l’accès serveur n’avait pas été sécurisé.
Rendre l’assainissement vérifiable, pas seulement “croire que c’est bon”
Après nettoyage, vous avez besoin d’une preuve. Sinon, vous revenez à la panique au premier signal de Google ou au premier screenshot d’un utilisateur.
Votre vérification doit être multiple :
Tester l’affichage côté navigateur, en session privée Vérifier le code source HTML reçu, pas uniquement l’impression visuelle Vérifier plusieurs pages, pas une seule URLJe recommande de choisir des pages représentatives : une page “qui était infectée”, une page de même template mais supposée saine, et une page d’un autre type (article vs page statique). Si l’injection est liée à un type de page ou à un template, votre test doit le refléter.
Si vous avez accès à un outil de surveillance (même simple), configurez un contrôle sur le domaine de script suspect ou sur un fragment unique. Cela évite les “faux retours” où la page semble clean pendant quelques jours, puis se dégrade.
Edge cases qui piègent même des gens prudents
Voici quelques situations qui reviennent souvent, parce qu’elles cassent l’intuition.
1) L’injection ne se voit pas dans la source “habituelle”
Parfois, le rendu injecté n’apparaît pas dans l’HTML statique initial, mais après exécution côté navigateur. Dans ce cas, la charge utile peut être chargée via un script externe, et vous ne la voyez qu’en inspectant les requêtes réseau.
2) La page “admin” est saine, la page publique est infectée
C’est un classique de logique conditionnelle. L’attaquant peut chercher à éviter la détection par les utilisateurs qui inspectent depuis l’admin. Résultat, vous passez du temps à nettoyer, puis vous gardez un mécanisme dans la sortie publique.
3) Le thème affiche un champ en base qui contient la charge
Le symptôme ressemble à “un problème de thème”. En réalité, le thème affiche simplement une option ou un champ qui a été injecté. Nettoyer le thème ne suffit pas, tant que la donnée en base n’est pas corrigée.
4) Une “correction” casse le builder
Si vous supprimez un bloc dans un builder, vous pouvez casser des sections légitimes. D’où l’intérêt de faire des exports avant suppression, et de comprendre ce que vous retirez. Dans les cas sensibles, une restauration du contenu à partir d’une version propre est parfois la méthode la plus sûre, même si elle prend plus de temps au départ.
Deux exemples typiques, pour situer la logique
Exemple 1 : injection globale dans plusieurs templates
Sur un site vitrine, l’équipe constate que toutes les pages changent, mais pas de manière identique. Après inspection du code source, on voit une balise script ajoutée au début du et des requêtes vers un domaine qui n’a aucun lien avec le site.
Le nettoyage a d’abord ciblé le thème. Rien d’anormal trouvé dans les fichiers principaux. La base, elle, contenait une option modifiée, utilisée ensuite par le thème pour ajouter des fragments personnalisés. Tant que l’option restait en place, la sortie continuait de porter la charge utile. Une fois l’option nettoyée et les comptes sécurisés (mots de passe et vérification des utilisateurs), l’injection a cessé.
Exemple 2 : injection ciblée sur une seule page, liée à un builder
Sur une page de formulaire, l’injection ne se voit que sur la page concernée. Les autres URLs restent intactes. Dans l’éditeur, le contenu “semble normal”. Pourtant, en HTML rendu, on trouve une portion de code injectée à la fin.
La piste la plus rapide a été de chercher le fragment dans la base. Il était présent dans un champ de page builder, stocké avec le contenu. Le thème ne faisait que rendre ce champ. Après suppression du fragment corrompu et remise à zéro du contenu du bloc incriminé, la page a été propre durablement.
Dans les deux cas, la clé a été la même : comparer le comportement, puis remonter à l’endroit exact où le rendu récupère l’information malveillante.
Plan de remise en production après traitement
Une fois l’injection supprimée, je travaille souvent avec un protocole simple pour éviter la réinfection silencieuse.
Je commence par une restauration propre des éléments modifiés (fichiers restaurés, base corrigée), puis j’applique les mises à jour nécessaires, et je réduis les plugins au minimum pour les tests. Ensuite, je réactive progressivement, en contrôlant à chaque fois l’HTML rendu sur les pages sensibles.
Ce que je veux éviter, c’est un scénario où vous remettez tout en ligne, puis un plugin ancien réintroduit une fonctionnalité vulnérable. Si le site dépend de ce plugin, vous pouvez remplacer le code vulnérable ou le mettre à jour, mais je préfère attendre que le plugin soit sain et testé avant de remettre pleinement la production.
Quand faire appel à un professionnel, ou au moins demander une seconde paire d’yeux
Vous pouvez traiter beaucoup de cas en interne, surtout quand vous avez des accès serveur et un bon niveau WordPress. Mais dans certains cas, il faut être pragmatique.
Si vous n’avez pas la capacité de comparer les fichiers à une version de référence, si vous n’avez aucun accès à la base, ou si le site est très modifié (multiples builders custom, thème enfant complexe, plugins sur mesure), le risque d’erreur augmente. Une injection “propre” visuellement, mais qui reste active dans un hook invisible, peut vous coûter cher, en temps de reprise et en perte SEO.
Un second regard aide aussi à ne pas rester bloqué sur un faux coupable, par exemple en rénovant le thème alors que la source est un champ en base ou un plugin inattendu.
Rappel pratique : votre priorité absolue pour les injections dans les pages
Quand un site WordPress infecté se manifeste par une injection dans les pages, votre priorité absolue est de relier le symptôme à la source exacte.
- Si vous voyez une logique globale, ciblez thème, plugins et hooks. Si c’est ciblé sur quelques pages, ciblez contenu et champs en base. Si ça revient, cherchez la persistance, comptes, tâche planifiée, mécanisme réinjectant.
C’est une approche moins “spectaculaire” que la suppression brute, mais elle réduit le temps total de traitement et augmente la probabilité d’un retour durable à la normale.
Si vous êtes en plein milieu d’un incident, dites-moi ce que vous observez exactement (type d’injection, pages touchées, présence ou non de code dans , et si c’est différent en session privée). Je pourrai vous aider à orienter le diagnostic, sans vous pousser vers des actions qui risquent de masquer la vraie source.