Un site WordPress peut partir d’un détail presque anodin. Un nouvel onglet “rapports”, une ligne de code ajoutée “pour mesurer les performances”, un plugin “analytics” qui n’a jamais existé hier. Puis, sans prévenir, vous voyez des comportements bizarres: trafic qui explose sur des pages inexistantes, redirections vers des domaines inconnus, ou des utilisateurs qui ne reconnaissent plus l’interface.
Dans la majorité des cas que j’ai vus sur des sites infectés, le point commun se résume à deux familles de nuisances: des iframe cachés et des scripts de tracking posés dans des endroits où ils ne devraient jamais être. Même quand le code semble “propre”, certains éléments suffisent à empoisonner le site de façon durable. L’objectif du nettoyage ne consiste pas seulement à supprimer le code visible. Il faut aussi comprendre pourquoi il a été injecté, et éviter la récidive.
Les symptômes typiques: quand l’iframe fait le travail sale
Les iframe malveillants sont particulièrement sournois. Ils peuvent être invisibles dans l’interface, parce qu’ils sont positionnés en CSS hors écran, avec des tailles minimales, ou encapsulés dans des blocs qui ne sont pas chargés partout. Sur un site infecté, on découvre souvent que certaines pages “chargent” pourtant une ressource externe au mauvais moment, ou qu’une requête mène à un domaine suspect.
La partie scripts de tracking malveillants suit souvent le même scénario. Au départ, un script se présente comme de la mesure, un pixel, un tag “marketing”. Ensuite, il commence à exfiltrer des informations de session, à déclencher des redirections, ou à déposer d’autres charges utiles. Ce n’est pas toujours un “virus” au sens classique. Dans l’écosystème WordPress, c’est plutôt une chaîne d’injection, avec des petites briques qui se complètent.
Quand on inspecte le HTML généré, on repère parfois des motifs récurrents: des iframe vers des domaines non liés, des événements onload ou onerror sur des balises inattendues, des scripts qui manipulent le DOM pour ajouter d’autres éléments, ou des appels à des endpoints qui ne ressemblent pas à de l’analytics légitime.
Où ces charges se cachent le plus souvent sur WordPress
WordPress a une architecture flexible, ce qui est une force, mais aussi une surface d’attaque. Les iframe et scripts malveillants se retrouvent fréquemment dans des emplacements “logiques” pour un attaquant, parce qu’ils permettent de persister même après un premier nettoyage.
Dans les cas réels, j’ai rencontré des injections dans:
- le fichier de thème, notamment des templates ou des fichiers inclus (footer.php, header.php, index.php), parfois avec une logique conditionnelle basée sur l’URL ou l’agent utilisateur la base de données via des champs inattendus, par exemple des options, des métadonnées de pages, ou des contenus de widgets injectés des zones administrables comme les éditeurs, mais aussi des paramètres de thème ou des champs “personnalisés” utilisés par certains builders des fichiers robots.txt ou des fichiers de réécriture qui déclenchent des comportements sur certaines routes, parfois en lien avec des redirections
Un détail important: l’injection peut être “propre” au premier abord. Un attaquant peut ajouter uniquement une petite ligne qui charge un script à distance, et c’est ce script externe qui exécute le reste. En inspection de surface, on croit avoir compris, puis on découvre que la charge utile ne réside pas sur le serveur.
Comprendre l’arme de persistance: pourquoi nettoyer sans vérifier échoue
Le nettoyage virus WordPress échoue rarement parce que la suppression est impossible. Il échoue parce que l’on supprime le symptôme, pas la cause. Si la porte d’entrée reste ouverte, le code revient.
La porte d’entrée la plus fréquente est l’accès en administration. Un compte compromis, un rôle trop permissif, un mot de passe réutilisé, ou une session qui n’a pas été révoquée. Ensuite, viennent les failles de plugins et de thèmes, y compris ceux qui ne sont pas mis à jour, et enfin les comportements liés aux fichiers modifiés en local, ou aux déploiements automatiques mal sécurisés.
Un autre piège arrive quand on “restaure” un fichier à partir d’un thème, mais que l’infection est dans la base de données. Dans ce cas, vous nettoyez les templates, puis vous constatez que le code réapparaît après un chargement d’une page. L’injection est toujours active côté DB, et les templates ne servent que de déclencheur.
Première étape pratique: préparer un nettoyage sans casser le site
Avant de toucher au code, je recommande de stabiliser le contexte. Sur un site en production, une correction rapide qui masque une erreur peut aggraver le problème. Voici comment je procède pour limiter le risque.

J’accorde d’abord une attention au navigateur et aux outils de contrôle. On cherche à observer le chargement avant modification, puis après suppression, pour vérifier si le comportement disparaît.
Ensuite, je sécurise l’environnement:
Faire une sauvegarde complète des fichiers et de la base, même si vous pensez “n’avoir qu’un petit morceau de code à enlever” Désactiver temporairement les plugins suspects, ou mettre le site en mode maintenance, si l’accès public déclenche l’injection Créer un snapshot du thème et des fichiers de configuration, pour pouvoir revenir rapidement si un motif conditionnel était essentiel au design Vérifier les comptes administrateurs et révoquer toutes les sessions actives avant de commencer les modificationsCette logique semble “lente”, mais elle évite des retours en arrière très coûteux.
Identifier les iframe et scripts: méthodes concrètes, sans magie
L’identification ne doit pas se limiter au “Ctrl+F”. Sur WordPress, le code peut être injecté dans des couches différentes, parfois compressées, parfois minifiées, parfois encodées.
La démarche qui marche le mieux consiste à coupler inspection et corrélation:
- Observer la page où le comportement apparaît, puis lire le HTML final rendu dans le navigateur (pas uniquement le code source de vos fichiers) Repérer les iframe vers des domaines externes, surtout si leur attribut src ne correspond à aucun service que vous utilisez clairement Chercher les scripts qui ne ressemblent pas à des tags standard (caractères bizarres, patterns de minification inhabituels, endpoints non connus) Identifier les emplacements WordPress où une injection peut persister (options, meta, contenu des widgets)
Sur un site infecté que j’ai aidé récemment, le “problème” ne s’affichait que sur une catégorie d’articles. En inspectant le HTML rendu, on a vu un iframe injecté dans le footer, mais l’entrée dans la base de données était conditionnelle. Autrement dit, le code ne se révélait pas sur toutes les pages. Sans cette observation, on aurait supprimé le code visible et laissé le déclencheur en place.
Le repérage rapide des patterns utiles
Quand on cherche des iframe, je garde un œil sur quelques signaux. Parfois, ce sont juste les indices qui orientent. Parfois, on trouve directement l’ensemble du bloc.

Voici une liste d’indices souvent pertinents (sans prétendre couvrir tous les cas):
- iframe avec un src vers un domaine inconnu, ou un domaine masqué via redirections iframe avec style “improbable” (display none, width ou height minuscules, position: absolute avec coordonnées) scripts chargés depuis des domaines qui ne correspondent à aucun plugin analytics connu ou à aucune configuration marketing balises script injectées dans des zones non cohérentes, par exemple juste autour d’un champ de widget ou d’un élément de menu utilisation d’événements inline (onclick, onload) sur des balises qui n’en avaient pas besoin
Une fois que vous repérez un motif, la question suivante est simple: d’où vient-il, dans WordPress, et comment y revenir proprement.
Nettoyer dans les fichiers de thème: supprimer le code sans casser la logique
Les fichiers du thème sont souvent la zone la plus “directe” pour injecter. Un attaquant aime lier l’injection à une condition légère, par exemple “si l’URL contient /product/…”, ou “si c’est un utilisateur connecté”. Résultat: le code peut rester invisible pendant vos tests.
La première règle est de ne pas supprimer au hasard. Si vous effacez un https://gardewp.fr/nettoyage-malware-wordpress/ bloc au milieu d’une fonction, vous pouvez casser le rendu ou casser une partie essentielle du thème.
Ce que je fais en pratique:
Je mets de côté une copie des fichiers touchés, avec dates et contenu, pour relire plus tard Je cherche le motif exact dans les fichiers du thème, puis je remonte la portion qui produit la sortie Je vérifie que le bloc supprimé n’est pas lié à un comportement légitime (tracking marketing, consentement cookies, ou scripts d’optimisation vraiment utilisés) Je remplace par une version saine, idéalement celle du thème en provenance de votre source (repo officiel, package de déploiement, ou archive constructeur)Une fois le code supprimé, je contrôle à nouveau le HTML rendu. Si le motif revient, c’est souvent un signe que l’injection est dans la base de données, ou que d’autres fichiers ont été modifiés.
Nettoyer dans la base de données: la partie la plus fréquente
Beaucoup de propriétaires regardent uniquement les fichiers, parce qu’ils ont l’impression que “c’est là que ça se voit”. Or, une injection DB peut être plus persistante, et elle peut rester active même si vos fichiers de thème sont intacts.
Selon la configuration, l’infection peut viser:
- des options WordPress (wp_options), où l’attaquant stocke du HTML ou des scripts insérés au moment du chargement des contenus de pages, via des champs texte ou des blocs ajoutés clandestinement des widgets ou des paramètres liés à des builders des métadonnées, par exemple des meta personnalisées que le thème affiche ensuite
Le nettoyage DB se fait avec prudence. Je recommande de commencer par isoler le contenu suspect. Une bonne stratégie consiste à rechercher des fragments stables que vous avez observés dans le HTML rendu: par exemple une balise iframe spécifique, un nom de domaine, une chaîne de fonction.
Ensuite, on supprime uniquement ce qui correspond au bloc malveillant. Si vous supprimez un champ complet sans comprendre, vous risquez de perdre de la mise en page ou une configuration utile.
Sur certains sites, l’injection est découpée: un petit fragment en DB déclenche un script externe, et ce script crée ensuite les iframes. Dans ce cas, supprimer l’iframe seule ne suffit pas, il faut aussi retirer le déclencheur.
Vérifier le rôle du navigateur et des caches: ne pas conclure trop vite
Une difficulté fréquente pendant le nettoyage, c’est la confusion entre infection et cache. Après suppression, certains éléments peuvent persister le temps de quelques minutes, voire plus longtemps, selon la stratégie de mise en cache.
J’ai déjà vu des cas où le code malveillant restait visible dans une version du site mise en cache via un CDN. Le propriétaire pensait que la suppression n’avait pas marché, alors que le navigateur chargeait encore une page ancienne. Il a fallu purger le cache, contrôler en navigation privée, puis revalider.
Vous gagnerez du temps si vous testez avec:
- une navigation privée un rechargement dur (selon votre navigateur) la purge du cache du site si vous utilisez un plugin la purge du cache CDN si vous en avez un
Sans ça, vous risquez de refaire un nettoyage destructif alors que le problème a été corrigé.
Sécuriser après suppression: empêcher le retour du tracking malveillant
Supprimer les iframe et scripts est nécessaire, mais ce n’est pas la fin du travail. Dans un scénario réaliste, l’attaquant a trouvé un moyen d’insérer du code, et il recommencera si rien n’est changé.
La sécurisation passe par un mix de nettoyage d’accès, durcissement, et mises à jour.
La partie “accès” est incontournable. Je commence par vérifier les comptes, puis les sessions. Je change ensuite les mots de passe des comptes critiques, surtout si un compte admin a été connecté récemment via des horaires suspects.
Ensuite viennent les mises à jour. Un site infecté révèle souvent un plugin obsolète, une version du thème trop ancienne, ou une configuration de sécurité incomplète.
Enfin, il faut limiter les surfaces d’injection. Certains rôles et droits d’édition peuvent être réduits. Si vous avez des contributeurs, assurez-vous qu’ils n’ont pas tous les droits d’administration.
Signaux d’alerte à surveiller après nettoyage (pour ne pas rater la récidive)
Une fois le nettoyage terminé, je ne “relâche” pas complètement l’œil. Il vaut mieux vérifier que les signaux restent stables pendant quelques heures, parfois une journée, selon la cadence de vos mises à jour et vos pics de trafic.
Voici des observations utiles:
- augmentation soudaine des requêtes vers des domaines externes non liés pages qui “reçoivent” à nouveau du HTML contenant iframe ou script inline nouveaux fichiers ou modifications sur les thèmes et plugins, alors que vous n’avez rien déployé comptes admin supplémentaires, ou changements de rôles traces de redirections vers des domaines externes, même si les iframe ont disparu
Sur un site, le piège était une page d’options, un champ qui contenait un fragment HTML. Après suppression, la page semblait propre, puis deux jours plus tard, le fragment revenait. On a compris que l’attaquant avait installé une logique conditionnelle ailleurs, qui réinjectait le contenu à chaque chargement. La surveillance a permis de repérer le retour avant que l’attaque ne s’intensifie.
Cas particulier: iframe légitimes, oui, mais lesquels ?
Tous les iframe ne sont pas forcément malveillants. On les utilise pour des vidéos, des formulaires, des intégrations de services, des widgets. Le problème n’est pas la balise iframe en soi, c’est ce que fait l’attribut src, et ce que le script déclenche autour.
Mon approche est pragmatique: si le domaine correspond à un service que vous utilisez réellement, et si le code est cohérent avec ce que votre équipe a mis en place, il n’y a aucune raison de supprimer. En revanche, si l’iframe charge un domaine inconnu, ou si son comportement ne correspond à aucun usage actuel, il faut le traiter comme un indicateur d’infection.
Il arrive aussi qu’un script légitime apparaisse minifié, mais qu’il soit injecté dans un endroit non prévu. Par exemple, vous avez un consentement cookies, mais le script de consentement n’est pas censé être injecté dans le contenu d’un article. C’est ce décalage qui alerte.
Exemple de démarche de diagnostic sur un site réel (sans jargon inutile)
Sur un site e-commerce, le propriétaire avait remarqué des performances dégradées. En vitesse de chargement, il voyait des temps plus longs, mais il ne comprenait pas pourquoi. En inspectant une page produit, j’ai trouvé un iframe en bas de page, chargé depuis un domaine qui n’était lié à aucune intégration déclarée.
Ensuite, on a recherché le domaine dans le HTML rendu sur plusieurs pages. Le motif apparaissait surtout sur les pages accessibles sans authentification. Ça indiquait que la condition était liée à l’URL et à l’état visiteur. On a ensuite cherché le fragment dans les fichiers de thème: il était présent dans un template du footer, avec une condition. Le contenu venait toutefois d’une option en base, ce qui voulait dire que le code pouvait revenir si l’option n’était pas supprimée.
La correction a donc été double: suppression du bloc dans le thème, suppression de l’option correspondante dans la base. Puis purge du cache. Enfin, réinitialisation des accès admin, et mise à jour du plugin utilisé pour la gestion de contenu, qui était en version trop ancienne. Après 24 heures, les signaux externes se sont normalisés, et le comportement ne s’est pas rechargé.
Ce type de cas illustre pourquoi un nettoyage “partiel” peut donner l’impression d’avoir réparé, tout en laissant une bombe à retardement.
Ce que je recommande pour réduire le risque à l’avenir
Le but n’est pas de transformer WordPress en forteresse impossible à maintenir. L’objectif est d’augmenter le coût de l’attaque, et de raccourcir le délai de détection.
D’après les cas que j’ai vus, les bonnes pratiques qui font vraiment une différence sont souvent assez simples: mises à jour régulières, accès admin protégés, et surveillance.
En pratique, je conseille de conserver une discipline de déploiement. Si un plugin ou un thème est mis à jour, faites-le de façon maîtrisée, et testez après chaque changement. Si un élément tracking doit être ajouté, passez par un canal clair, et documentez le domaine utilisé et l’objectif. Quand un code arrive “par magie”, c’est un drapeau rouge.
Plan d’action final, version opérable
Pour finir, voici une manière de structurer le nettoyage de façon réaliste, sans perdre de temps.
- localiser le code exact dans le HTML rendu, puis remonter aux fichiers et aux zones DB responsables supprimer les iframe et scripts de tracking malveillants, en conservant les blocs légitimes quand ils sont identifiables purge cache, puis test en navigation privée pour vérifier la disparition réelle du comportement révoquer sessions, vérifier comptes et rôles, puis changer les mots de passe des comptes critiques mettre à jour plugins et thèmes, et vérifier que le point d’entrée n’existe plus
Ce plan évite l’erreur la plus coûteuse: nettoyer une fois, constater une amélioration, puis subir une réinfection parce que la porte d’entrée n’a pas été fermée.
Si vous êtes dans une phase d’urgence, commencez par le repérage dans le HTML rendu et la suppression du déclencheur. Ensuite seulement, sécurisez. Le cœur du problème, ce sont ces iframe et scripts de tracking malveillants qui prennent l’habitude de revenir tant que WordPress reste accessible via une voie compromise.
Avec une méthode propre, vous pouvez https://gardewp.fr/ arriver à un site stable, et surtout à un site qui ne redonne pas à l’attaquant la possibilité de rejouer la même scène.
