WordPress est devenu un terrain d’enquête familier. Pas parce que le CMS serait “plus fragile” que d’autres, mais parce qu’il attire la même énergie que la lumière attire les insectes. Dès qu’un site prend de la visibilité, on y voit apparaître des scripts qui n’ont rien à faire là, des redirections étranges, des pages qui “s’ajoutent toutes seules”, ou encore des tentatives d’implantation via des formulaires et plugins pas toujours mis à jour.
Quand on parle de scanner malware WordPress, la tentation est de croire que l’outil suffit. Il aide, oui, mais il ne comprend pas à la place de votre contexte. Le vrai travail commence souvent au moment où le rapport vous signale “un script suspect”, “une URL non autorisée” ou “un fichier modifié”, puis vous devez remonter la chaîne d’intégration. Qui l’a injecté, par quel mécanisme, et surtout à quel moment.
Je vous propose une méthode pragmatique, centrée sur un point précis: vérifier l’intégration de scripts tiers suspects. C’est là que beaucoup de problèmes se révèlent, et c’est aussi là qu’on peut éviter de casser le site en traitant trop vite.
Le scénario le plus fréquent: ce n’est pas “le malware”, c’est l’intégration
Beaucoup de contaminations sur WordPress se matérialisent moins par un “grand fichier” malveillant que par une modification discrète. Le code reste souvent petit, il s’accroche à un endroit logique (entête, pied de page, fichier de template, plugin d’analytics, gestionnaire de consentement), et il se contente de charger quelque chose à distance.
Ce qui trompe, c’est la manière dont cela s’insère. Un script peut être injecté depuis:
- un plugin qui gère des publicités ou des tags, une extension de “performance” ou de “SEO”, une mise en page qui ajoute des éléments via un champ “header” ou “footer”, ou un mécanisme d’inclusion côté thème via functions.php, header.php ou un fichier template.
Le malware, dans ce cas, ressemble à un prestataire de tracking qui a mal été configuré. La différence se voit quand on examine les détails. Pas les gros titres du rapport de scan.
Sur un site que j’ai audité récemment, le scanner malware WordPress affichait une alerte liée à un script dans le footer.php. En ouvrant le code, on trouvait un ajout minuscule, une instruction qui récupérait une URL via un paramètre et qui chargeait ensuite un JavaScript. La chaîne complète n’était pas évidente pour l’outil, mais pour un humain, le comportement était clair: ce n’était pas un script de suivi standard, c’était un chargeur.
Comprendre ce que “script tiers suspect” veut dire, sans se raconter d’histoires
Un script tiers, c’est un script servi depuis un domaine externe. Certains sont légitimes, d’autres non. Mais le terme “suspect” devient utile uniquement quand il renvoie à un comportement observable.
Les indices qui reviennent souvent:
- le script est injecté dans des fichiers de thème alors qu’il devrait être dans une configuration de plugin, le domaine chargé n’est pas aligné avec les outils annoncés par le site (analytics, pixel, chat, SEO), le code est minifié de manière inhabituelle, avec des fonctions de déchiffrement ou de base64, il y a des redirections, des exfiltrations de données, ou des appels vers des routes qui ne correspondent pas à l’activité du site, le script s’active seulement sur certains navigateurs, géolocalisations, ou contenus.
Le piège, c’est de confondre “script inconnu” et “script malveillant”. Un script inconnu peut tout simplement être un outil marketing déployé récemment, ou un tag oublié dans une solution d’intégration. L’inverse existe aussi: un script malveillant peut s’appuyer sur un domaine qui ressemble à quelque chose d’authentique, le genre d’imitation qui ne saute pas aux yeux.
Mon réflexe consiste à traiter l’alerte comme une enquête, pas comme un verdict.
Localiser exactement où le script est injecté
Avant d’accuser un plugin, avant même d’ouvrir tous les fichiers, je commence par un inventaire minimal. L’objectif est simple: retrouver le point d’entrée.
Le plus efficace est de combiner trois observations:
Ce que le scanner malware WordPress signale (fichier, chemin, règle, signature), Ce qu’on voit dans le HTML rendu (le script est-il dans le code source de la page, ou ajouté côté navigateur), Et ce qui change selon la page, l’utilisateur, ou le temps.Un script injecté dans le rendu HTML peut être présent dans une page précise, par exemple sur les pages publiques https://gardewp.fr/ mais pas sur l’admin. Un script injecté côté navigateur via une extension compromise peut se manifester différemment.
Concrètement, je regarde toujours:
- le chemin exact du fichier (thème, sous-thème, plugin, dossier uploads), si le code se trouve dans une fonction (par exemple wp_head, wp_footer) ou dans un template (directement dans header.php), et si l’injection dépend d’une condition (is page, isadmin, utilisateur, langue).
Si le scanner fournit un chemin, c’est un bon départ. S’il ne fournit qu’une idée vague, il faut revenir au rendu HTML et chercher les signatures du code chargé, même sous forme minifiée.
Vérifier la présence d’appels “dynamiques” et de domaines incohérents
Les scripts suspects ont souvent un trait commun: ils ne chargent pas juste une URL. Ils manipulent, construisent, ou récupèrent des paramètres. Le comportement “chargement dynamique” est un drapeau, surtout quand il est placé dans le mauvais endroit.
Quelques exemples d’indices que je considère comme des signaux sérieux:
- utilisation de eval, Function, ou de décodage type base64 suivi d’un exécutable, création de script en JavaScript (appendChild, setAttribute) au lieu d’un tag statique, chargement d’une ressource depuis une chaîne construite à partir de fragments, présence d’URL qui ne correspondent à aucun fournisseur déclaré par le site.
Ce n’est pas parce qu’un script est minifié qu’il est dangereux. Mais sur WordPress, l’ajout furtif qui “semble faire quelque chose” sans objectif marketing clair mérite une lecture.
Une bonne pratique que j’adopte: noter le domaine exact chargé (celui du script, pas seulement celui qui injecte). Puis comparer ce domaine avec les outils que le site utilise réellement, soit via la documentation interne, soit via ce que vous trouvez dans la configuration des plugins (Tag Manager, consentement, retargeting, etc.).
Si le domaine n’est associé à rien, je continue l’enquête.
Cartographier les chemins possibles dans WordPress
Quand vous cherchez l’intégration, vous devez cartographier les mécanismes qui permettent d’ajouter du JavaScript sans toucher aux templates principaux. WordPress offre plusieurs portes, et les attaquants adorent celles qui ont l’air “normal”.
Trois portes reviennent très souvent dans les cas d’injection:
- les hooks du thème et des plugins, comme wp_head et wp_footer, les champs “custom code” (header, footer, scripts) dans certains plugins, les shortcodes ou blocs qui affichent du code dans des pages spécifiques.
J’ai vu des cas où le thème n’avait pas été modifié directement. Le code suspect venait d’un plugin “perf/ads” qui utilisait un champ optionnel. Le scanner malware WordPress alertait sur un fichier précis, mais la vraie cause était ailleurs: un plugin configuré pour insérer du contenu. Dans ce cas, vous pouvez “nettoyer” le fichier signalé et le malware revient dès que WordPress reconstruit la sortie.
Donc, l’étape importante consiste à comprendre la chaîne: d’où vient la variable qui déclenche l’injection.
Inspecter les fichiers du thème avec une logique d’intégrité
Quand l’alerte concerne un fichier de thème, l’inspection ne doit pas se limiter à chercher un bout de texte. Je fais plutôt une lecture orientée intégrité.
Je cherche:
- si la modification est isolée à une zone précise (footer, head, ajout d’un tag), si le reste du fichier est identique à une version attendue, si la modification est récente (à travers les dates de modification, même si ce n’est pas une preuve absolue), et si la syntaxe est cohérente avec du code “humain” ou si c’est un collage.
Dans WordPress, les thèmes changent souvent. Donc je compare avec une base de référence quand c’est possible: une copie du thème depuis un dépôt, ou une version publiée au moment du déploiement. Si vous n’avez pas cette base, faites au moins une comparaison entre le fichier suspect et les versions d’autres fichiers similaires du même thème. Les attaquants ont parfois tendance à répéter des motifs.
À ce stade, vous pouvez tomber sur un cas simple: une balise
Si le code envoie vers uploads ou un dossier “cache”, je redouble d’attention.
Exploiter les hooks: trouver quel code “déclenche” l’injection
C’est souvent le moment où les choses deviennent plus techniques, mais aussi plus claires. Si le script est injecté via wp_head ou wp_footer, il y a un “callback” derrière.
Une approche robuste consiste à activer temporairement une méthode d’observation côté site (sur un environnement de staging idéalement). Par exemple, vous pouvez vérifier quelles fonctions sont ajoutées à ces hooks, via une trace. Selon votre niveau, vous pouvez aussi utiliser des plugins de diagnostic (ils ne sont pas “magiques”, mais ils vous donnent une visibilité).
Le point clé reste le même: trouver le callback qui ajoute le code. Ensuite seulement, vous regardez le fichier source du callback.
Cette méthode évite le piège classique: corriger un fichier de template là où le vrai déclencheur est un plugin, ou l’inverse.
Cas particulier: les plugins “code snippets” et les champs custom
Certains plugins permettent d’insérer du code arbitraire dans le thème. Ils sont pratiques pour ajouter des pixels, des scripts de chat, des balises SEO, ou des tags publicitaires. Ce sont aussi des surfaces d’attaque idéales si un compte est compromis.
Quand je vois un script tiers suspect, je vérifie d’abord si un plugin d’extrait de code est installé, et s’il a des entrées actives. Même si la configuration “a l’air” propre dans l’interface, le contenu peut être caché ou modifié.
Ce que je fais dans ces situations:
- je recherche des entrées actives qui contiennent le domaine chargé dans le script, je vérifie si le plugin est activé sur tout le site ou sur des conditions, je compare l’entrée avec ce que l’équipe marketing ou la personne en charge des tags déclare utiliser.
Il arrive aussi que l’attaquant ajoute directement un fragment via l’interface, par exemple dans un champ “footer scripts”. Vous le verrez en lisant la configuration, pas en inspectant seulement les fichiers du thème.
Si le scanner ne pointe pas le bon fichier: regarder les bases de données et les options
Certaines injections passent par la base de données. WordPress stocke beaucoup de configuration dans des options et des métadonnées. Un script peut être injecté depuis une option, puis ajouté au rendu via un hook.
C’est un cas où il faut résister à une réaction impulsive. Nettoyer des fichiers ne suffit pas si l’injection est pilotée par une donnée en base.
Je traite ce scénario en deux temps:
- d’abord, identifier la source de la donnée (option, meta, ou post meta), puis, confirmer la chaîne d’utilisation dans le code.
Si vous tentez des suppressions à l’aveugle, vous risquez de casser une configuration légitime. Par exemple, un plugin de consentement peut stocker des balises dans une option. Supprimer l’option sans comprendre le plugin peut provoquer une régression, ou un changement de comportement juridique et technique.
Quand le script suspect est en base, le “nettoyage” ressemble plus à une correction de configuration qu’à une suppression de fichiers.

Vérifier le réseau: observer les requêtes et comprendre le moment d’exécution
Même avec une inspection du code, le réseau apporte une confirmation immédiate. Un script malveillant cherche souvent à charger une ressource au bon moment: après un délai, après interaction, ou selon un contenu.
Sur un site en production, je fais cette observation avec prudence. L’idéal est de reproduire sur une page de test sans données sensibles. Ensuite, via les outils de développement du navigateur, je regarde:
- l’ordre des requêtes, les domaines contactés, les réponses HTTP inattendues, et si une redirection se produit.
Le bénéfice est double: vous confirmez le domaine réellement chargé et vous repérez des comportements d’exfiltration ou de redirection avant même de “comprendre” le code.
Une anecdote utile: sur un cas, le code affichait un chargement vers un domaine qui ressemblait à un CDN. Sur le réseau, on voyait que le script déclenchait ensuite un appel qui renvoyait vers une URL interne de type “tracking endpoint” inexistante. Cette incohérence était le signe que ce n’était pas un usage marketing standard.
Définir une décision: corriger, isoler, ou désactiver temporairement
Une fois l’intégration identifiée, il reste une question pragmatique: que faire ensuite. Trois options existent, avec des trade-offs.
Si le script est clairement injecté par une configuration légitime mais mal réglée, vous corrigez la config. Si c’est un plugin compromis, vous isolez le plugin. Si c’est une injection dans le thème ou dans des fichiers modifiés, vous remplacez les fichiers par une version saine et vous traquez la source.
Le piège, c’est de remplacer sans comprendre. Si le plugin ou l’option en base continue d’injecter, le problème reviendra. Inversement, si vous désactivez un plugin sans vérifier, vous cassez des fonctionnalités et vous perdez un indice utile sur l’intégration.
Je préfère une logique d’enquête. On conserve des traces, on documente le comportement avant intervention, puis on applique une correction ciblée.
Checklist rapide de vérification (scripts tiers, sans se tromper de cible)
Quand j’ai besoin d’avancer vite, j’utilise une micro-checklist, limitée, orientée “preuve”.
- Relevez le domaine exact chargé par le script suspect, et pas seulement le nom dans le rapport. Localisez le point d’injection dans le HTML rendu, puis comparez avec les fichiers de thème et les hooks concernés. Vérifiez s’il existe une option ou un champ de plugin qui contient ce même fragment ou ce même domaine. Contrôlez le réseau pour voir quand et comment la requête démarre (délai, interaction, page spécifique). Si le déclenchement passe par un plugin, validez l’historique de déploiement et les comptes qui ont pu modifier la configuration.
Cette approche réduit les “faux positifs” et surtout les corrections destructrices.
Nettoyer sans casser: le piège des “fichiers remplacés à la hâte”
Le nettoyage le plus rapide, c’est parfois de remplacer un thème ou de supprimer un plugin. Ça peut fonctionner. Mais sur WordPress, la contamination peut rester dans la base de données ou dans un autre plugin, et alors vous revenez au même problème en quelques heures.
Une règle mentale qui m’aide: avant de remplacer, vérifiez si la source est:
- un fichier du code (thème, plugin, uploads), ou une donnée (option en base, meta, settings de plugin), ou une habitude d’injection via un hook.
Si vous remplacez sans traiter la source, vous “effacez le symptôme”, et le symptôme se réinstalle.
Pour les fichiers, je recommande de revenir à une base saine, idéalement une version versionnée du thème, ou un dépôt officiel. Pour les options et métas, on corrige spécifiquement les valeurs ou on réinitialise en comprenant la configuration du plugin concerné.
Le bon tempo, c’est de faire des changements limités, puis de re-tester.
Comment tester après correction, pour être sûr que l’intégration est partie
Tester après correction n’est pas un détail. Sans test, vous êtes aveugle, et vous risquez de reposer une confiance fragile sur un scanner malware WordPress.
Je procède généralement ainsi:
- je rafraîchis les pages concernées et je re-regarde le HTML rendu (l’injection a-t-elle disparu), je contrôle le réseau, surtout au moment où le script se déclenche, je vérifie que le site se comporte normalement sur les pages à fort trafic (accueil, pages indexées, pages de formulaire), et je teste aussi l’accès admin, sans quoi certaines injections peuvent rester silencieuses.
Si vous aviez un plugin de consentement ou un gestionnaire de tags, testez aussi la logique de consentement. Un script peut sembler “enlevé” mais revenir quand le consentement est accordé.
Renforcer après: empêcher la réinfection au prochain incident
Une fois que l’intégration suspecte est supprimée, la question devient: comment éviter qu’elle revienne.
Là encore, l’approche ne doit pas être purement technique. Une partie du risque vient du contrôle des comptes, des permissions, et du cycle de déploiement.
Les mesures les plus utiles, sans tomber dans le catalogue:
Vérifier que les comptes admin n’ont pas été créés ou modifiés sans raison. Révoquer les sessions suspectes si vous avez accès au panneau d’hébergement. Mettre à jour le noyau WordPress, les thèmes et les plugins, en particulier ceux liés aux scripts tiers. Limiter l’installation de plugins, ou imposer une validation interne pour ceux qui injectent du code. Surveiller les fichiers et les changements de configuration.Je sais, tout le monde le dit. Mais ce qui change la donne, c’est l’application concrète à votre parc. Si vous n’avez qu’une personne qui modifie tout “à la demande”, vous aurez toujours des injections par surprise.
Deuxième checklist, orientée “source et cause” (pas uniquement suppression)
Quand l’investigation se termine, je veux être certain que la cause est traitée, pas seulement le symptôme. Voilà ma checklist finale:
- La valeur ou le fichier à l’origine de l’injection a-t-il été supprimé ou corrigé, pas seulement “masqué”. Le mécanisme d’intégration (hook, champ plugin, shortcodes, option en base) ne réinjecte-t-il plus le script au rendu. Un autre composant (autre plugin, autre option, autre thème) n’a pas conservé une version de la même logique. Les domaines contactés par le script suspect n’apparaissent plus au niveau réseau sur les pages concernées. La source d’accès (compte, rôle, historique) qui a permis la modification est-elle comprise et corrigée.
Si vous cochez ces points, vous avez une chance réelle de sortir du cycle “scan, nettoyage, retour”.
Ce que j’attends d’un rapport de scan malware WordPress, et ce que je n’y crois pas
Les scanners sont utiles, mais ils ont leurs limites. Je ne m’appuie pas sur eux comme sur une preuve judiciaire. Je les utilise comme un radar: ils m’indiquent des zones où regarder, parfois des patterns, parfois une liste d’indicateurs.
Ce que je sais par expérience, c’est qu’un scanner peut:
- détecter un fragment déjà supprimé, confondre un script légitime minifié avec une signature de malware, pointer un fichier qui a été touché, sans que ce fichier soit la source initiale.
Donc, la valeur est dans le duo “rapport + observation”. Le rapport m’oriente, l’inspection et le réseau confirment.
Le meilleur résultat que j’ai vu, c’était quand le rapport m’indiquait précisément un fichier, et que l’analyse du hook montrait clairement le déclencheur. À l’inverse, le pire, c’est quand on remplace tout sans comprendre, et que le script revient parce que la source était une option de plugin.
Micro-guide de lecture du code, pour gagner du temps
Quand vous ouvrez le fragment suspect, le but n’est pas d’être un ingénieur reverse. Le but est de repérer les motifs d’intention.
Je regarde en priorité:
- la logique d’activation (conditions, délais), les fonctions qui encodent ou décodent, les variables qui construisent une URL, les sorties (document, window, redirection), et les références à des domaines externes.
Si vous ne comprenez pas tout, c’est normal. En pratique, vous pouvez déjà décider en observant le rôle du code: est-ce un tag marketing classique, ou un chargeur de contenu.
Et si le fragment est trop opaque, le réseau vous ramène à une vérité concrète: qu’est-ce qui est réellement chargé par le navigateur, et dans quel contexte.
Conclusion pratique qui n’en a pas besoin: traiter l’intégration, pas l’étiquette
Le scanner malware WordPress est un point de départ, pas la fin de l’histoire. Quand l’alerte concerne l’intégration de scripts tiers suspects, la démarche la plus efficace reste d’identifier le point d’injection, puis la mécanique de déclenchement, et enfin la source de données ou de configuration qui rend l’intégration persistante.
C’est un travail de patience, mais il a un avantage. Une fois que vous avez compris votre chaîne d’intégration, vous améliorez aussi votre capacité à prévenir les prochains incidents: vous savez quels plugins ont le droit de toucher au rendu, quels champs custom surveiller, et comment vérifier rapidement que le HTML servi et le réseau observé correspondent à l’intention.
Si vous voulez, décrivez votre situation en quelques éléments concrets (nom du plugin concerné s’il y en a un, chemin du fichier signalé, domaine exact chargé, pages où l’on voit l’effet). Je peux vous aider à orienter l’enquête vers la source la plus probable, sans partir dans des suppositions.