Quand on tombe sur un site WordPress qui “s’est mis à attaquer”, on a souvent déjà vu quelques symptômes: pages qui deviennent des redirections, formulaires qui semblent fonctionner puis partent ailleurs, accès utilisateurs impossibles à expliquer, ou encore des fichiers fraîchement modifiés sans raison. Dans les cas d’injection, le scénario le plus fréquent est simple: un attaquant parvient à déposer du code dans l’arborescence du site, puis s’appuie sur WordPress pour l’exécuter. Et parmi les emplacements qui reviennent le plus, il y a wp-content et tout ce qui tourne autour de ses sous-dossiers.
Cet article parle d’un cas très concret: corriger une injection déposée dans wp-content sur un site WordPress infecté. L’objectif n’est pas seulement de “nettoyer”, mais aussi de retrouver un état sain, empêcher la repousse, et remettre en ligne sans laisser une bombe silencieuse.
Comprendre ce que fait une injection dans wp-content
wp-content n’est pas un dossier “annexe”. WordPress y stocke les thèmes, les extensions, les uploads, et parfois d’autres fichiers ajoutés par des intégrations. Autrement dit, c’est aussi l’endroit que l’attaquant connaît bien, parce que son code peut se cacher dans un plugin, dans un thème, dans un fichier temporaire, ou dans une logique d’upload.
Le point clé est la chaîne d’exécution. Un attaquant cherche généralement à obtenir une de ces situations:
Son code se charge à chaque page via un require, un include ou un hook WordPress. Son code modifie le comportement de WordPress à l’aide d’un fichier “fourre-tout”. Son code se déclenche au moment du chargement d’un média, d’une ressource, ou d’une action Ajax.Souvent, on voit des fichiers ajoutés, parfois avec des noms peu lisibles. Parfois, ce sont des fichiers existants qui ont été modifiés. Plus piégeux encore: une injection qui ne se remarque pas par le contenu, mais par le fait que WordPress l’exécute via un enregistrement côté PHP.

Dans un atelier réel, j’ai déjà vu un site où le fichier ciblé ne semblait contenir “que” quelques lignes au début. Le reste était encodé, compressé, ou découpé entre plusieurs variables. Le PHP ne crie pas, il fait juste son travail une fois exécuté.
Les premiers signaux qui guident l’enquête
Avant même de “supprimer”, il faut observer. Pas pour perdre du temps, mais parce que l’analyse des traces aide à choisir la bonne stratégie de restauration.
Un site WordPress infecté montre rarement un seul signe isolé. Typiquement, le comportement change en parallèle, et ce sont ces changements qui indiquent la nature de l’injection.
Voici les indices les plus utiles, ceux qui reviennent en pratique dans les cas d’injection dans wp-content:
- modifications d’horodatage incohérentes sur des fichiers PHP dans wp-content/plugins ou wp-content/themes nouveaux fichiers avec des noms atypiques, souvent proches de chaînes aléatoires présence de code “glue” dans des fichiers qui ne devraient rien faire (par exemple une logique qui déchiffre, télécharge, ou appelle une URL) redirections ou chargements externes visibles dans le HTML ou dans les logs serveur augmentation soudaine des erreurs PHP, ou des appels répétés à des routes qui n’existent pas en temps normal
Si vous ne disposez pas des logs, le travail devient plus dur, mais pas impossible. Dans ce cas, le plan repose davantage sur l’intégrité des fichiers, et sur une restauration contrôlée.
Stabiliser le site avant de toucher aux fichiers
La tentation est grande de supprimer le fichier suspect immédiatement. C’est compréhensible, mais il y a un risque: si l’injection a aussi modifié la base de données, ou si un plugin “retient” la capacité de réécrire des fichiers, vous pourriez juste casser l’affichage sans corriger la cause.
Je recommande une stabilisation avant la correction:
- Passez le site en mode maintenance si vous pouvez le faire sans casser davantage (ou mettez temporairement une règle de pare-feu). Bloquez le trafic entrant non indispensable si votre pare-feu le permet. Désactivez le compte admin compromis si vous identifiez un accès frauduleux, mais ne supprimez pas tout trop vite. Récupérez une copie du serveur de fichiers et de la base, idéalement en double, pour pouvoir revenir.
Le but est simple: vous voulez une fenêtre où l’environnement ne continue pas à se dégrader, et où vous pouvez auditer les changements.
Localiser l’injection dans wp-content sans partir à l’aveugle
Pour corriger proprement, il faut d’abord répondre à une question: quel fichier exécute le code malveillant.
Dans WordPress, les injections “sales” se manifestent souvent dans:
- un fichier PHP ajouté dans un plugin ou un thème une fonction déclenchée par un hook une inclusion conditionnelle, par exemple selon l’agent navigateur, l’IP, ou une requête spécifique
Une méthode robuste consiste à utiliser la comparaison d’intégrité. Si vous avez un accès à un historique ou à une base saine (clone avant incident), comparez. Sinon, comparez avec une version officielle du thème ou du plugin, en tenant compte des mises à jour.
J’ai vu des injections où le fichier suspect était dans wp-content/uploads, mais le chargement était déclenché par une logique dans un plugin. Dans ce cas, chercher uniquement dans uploads vous donne l’arbre, mais pas la racine. Les traces côté PHP dans les plugins et thèmes restent prioritaires.
Ce qu’il faut rechercher dans le code suspect
Une difficulté fréquente, c’est l’analyse du PHP. Le code malveillant n’est pas toujours “brut”. Parfois il est encodé avec des fonctions, parfois il s’appuie sur des chaînes de caractères longues pour masquer le vrai comportement.
Sans tomber dans le “tout le monde sait”, voilà des patterns typiques que j’ai rencontrés dans des injections:
- présence de fonctions de déchiffrement ou de décodage, par exemple des combinaisons qui reconstruisent du code à l’exécution appels à des fonctions système (ou proches), ou des fonctions qui lisent des fichiers et les réécrivent utilisation de base64_decode, gzinflate, str_rot13 ou autres transformations téléchargement de contenu externe vers un fichier dans wp-content ou exécution directe logique qui vérifie l’environnement, puis ne s’active qu’à certaines heures ou conditions
Important: ne confondez pas cela avec un plugin légitime qui pourrait utiliser de l’encodage pour un cache ou une optimisation. La différence se voit dans le contexte. Un plugin sérieux n’essaie pas de télécharger du code exécutable en tâche de fond, et n’enregistre pas des fichiers PHP générés dynamiquement sans raison claire.
Si vous hésitez, testez sur une copie. L’analyse “production” est rarement la meilleure idée.

Correction: stratégie de nettoyage et restauration contrôlée
Une correction efficace repose sur un principe d’hygiène: ne vous limitez pas à effacer un fichier, corrigez l’ensemble des vecteurs qui permettent à l’injection de revenir.
En pratique, il y a trois scénarios principaux:
L’injection est limitée à un fichier isolé dans wp-content. L’injection est disséminée dans plusieurs fichiers, souvent via un plugin compromis. L’injection a aussi touché la base de données (options, cron, utilisateurs, ou hooks sauvegardés).Selon le scénario, la correction change. Dans les cas sérieux, je préfère une approche “rebuild” partielle: restauration depuis une version saine pour les composants suspects, puis purge des traces en base.
Plan d’action concret (sans bricolage dangereux)
Voici un déroulé qui marche bien quand l’injection est dans wp-content et que vous voulez retrouver une base stable:
- Isoler le site (maintenance, pare-feu, blocage des accès suspects) pour empêcher la repousse. Dresser l’inventaire des fichiers modifiés récemment dans wp-content et identifier ceux qui ont été ajoutés. Remplacer les thèmes et plugins suspects par des versions propres (idéalement depuis le dépôt officiel ou vos artefacts internes). Vérifier la base de données pour les options, cron, ou champs qui contiennent des hooks ou des scripts inattendus. Contrôler l’accès: mots de passe, rôles, clés API, et supprimer les comptes non légitimes.
C’est volontairement direct. Le piège, c’est de corriger uniquement le fichier vu, puis d’oublier une autre porte d’entrée.
Faut-il remplacer ou “corriger à la main” un plugin ou un thème ?
Quand vous trouvez un plugin ou un thème touché, vous avez deux options: patcher le fichier suspect à la main, ou remplacer par une version propre.
Dans la majorité des cas que j’ai traités, le remplacement est plus fiable, pour une raison simple: l’attaquant peut avoir modifié plusieurs endroits dans le même composant. Parfois le fichier additionnel est petit, mais la logique réelle est ailleurs, dans un autre fichier chargé par un autoload ou par un hook.
Le remplacement réduit aussi le risque d’avoir oublié une micro-modification. Le patch “à la main” marche uniquement si vous êtes certain de la surface d’attaque et que vous pouvez prouver qu’il ne reste aucune altération.
Il y a toutefois un compromis. Si vous avez un thème custom, ou des plugins avec modifications internes, https://gardewp.fr/ le remplacement peut casser des fonctionnalités. Dans ce cas, vous remplacez seulement les fichiers douteux par ceux de la version correcte, puis vous comparez les différences pour conserver le custom propre.
Vérifier les déclencheurs: cron, options, et injections persistantes
Même si le code est dans wp-content, la persistance peut être pilotée depuis la base de données. WordPress utilise des options et des événements planifiés, et un attaquant peut y stocker une instruction.
Un symptôme clair, c’est quand le fichier malveillant disparaît, mais que le site continue à rediriger, ou que des fichiers réapparaissent sans cause évidente. Dans ces cas, j’ai vu des injections associées à:
- des tâches cron qui téléchargent ou régénèrent un fichier dans wp-content des options qui changent le comportement global (souvent liées aux redirections ou à l’injection de contenu) des données de plugin mal modifiées, notamment des champs où WordPress enregistre des paramètres d’exécution
La vérification doit être méthodique. Ne coupez pas “au hasard” des lignes en base sans comprendre. Le meilleur réflexe reste une sauvegarde, puis une restauration ciblée. Si vous avez une copie saine avant incident, comparez. Sinon, cherchez les champs contenant des URL externes, des chaînes de décodage, ou des segments PHP.
Gestion des accès: le compte n’est pas toujours la seule porte
Un compte compromis explique souvent l’incident, mais pas toujours. Parfois, l’attaquant exploite une vulnérabilité sans réussir à rester connecté. D’autres fois, il laisse une porte ouverte après coup.
Quand vous nettoyez une injection dans wp-content, je vous conseille de traiter aussi le volet accès, même si vous n’avez pas vu de connexion suspecte dans l’interface.
Sur un chantier, j’ai déjà observé une situation où les mots de passe avaient été changés rapidement par le client, mais où l’attaquant avait gardé l’accès via une clé ou via un compte secondaire. Résultat: dès que les fichiers suspects ont été supprimés, le système a reconstruit le contenu malveillant.
Sans multiplier les étapes inutiles, vérifiez au minimum:
- les utilisateurs WordPress existants, leurs rôles, et leurs dates de création les connexions récentes côté serveur si vous avez les logs les plugins de sécurité et leurs réglages d’intégrité les méthodes d’accès externes (FTP, SFTP, clés SSH, accès au panneau d’hébergement)
Une injection qui “revient” est rarement juste un fichier. C’est une stratégie.
Mesurer l’ampleur: comment savoir si c’est “réparé” ou juste “coupé”
Après la correction, le danger n’est pas uniquement la repousse. Le danger, c’est de laisser un mécanisme latent: un coin de code qui ne s’active que pour certains utilisateurs, certains User-Agent, ou certaines heures. Ce comportement rend les tests classiques trompeurs.
Pour vérifier sérieusement, utilisez plusieurs angles:
- test sur plusieurs navigateurs, y compris mobile test de plusieurs pages, surtout celles qui étaient touchées contrôle du code HTML livré en réponse, pour repérer des scripts injectés vérification des fichiers PHP dans wp-content via un scan d’intégrité et une comparaison avec une version saine surveillance serveur après remise en ligne (trafic, pics d’erreurs PHP, accès à des endpoints inutiles)
Le point de bascule arrive quand vous ne voyez plus d’actions anormales sur quelques heures, voire une journée complète selon la volumétrie. Si vous avez un trafic faible, attendez plus longtemps, sinon vous ne verrez pas le déclenchement conditionnel.
Cas particulier: injection via uploads et déclenchement depuis un plugin
Il arrive que l’injection “vive” dans wp-content/uploads, mais qu’elle soit déclenchée par un mécanisme côté plugin. Vous pouvez alors avoir une confusion, parce que le fichier d’uploads semble inoffensif.
Dans ces cas, la logique que je cherche est la suivante: quel fichier PHP charge l’upload ou en utilise le contenu? Souvent, un plugin compromis tente de résoudre une ressource ou d’exécuter un comportement via un champ ou une URL.
Le correctif, c’est de traiter le plugin compromis même si le symptôme “se trouve” dans les uploads. Sinon, vous supprimez le fichier, il revient. Le système n’a pas de raison d’arrêter de générer.
Protéger sans casser: hardening après nettoyage
Nettoyer sans améliorer la sécurité, c’est accepter de revivre l’histoire. La bonne approche dépend de votre environnement, hébergement mutualisé ou serveur dédié, présence d’un WAF, nature des plugins.
Le hardening le plus rentable après une injection dans wp-content consiste souvent à:
- réduire les permissions d’écriture là où ce n’est pas nécessaire appliquer les mises à jour WordPress, thèmes et plugins, surtout ceux exposant une surface activer une surveillance d’intégrité des fichiers (au moins sur les dossiers clés) imposer des mots de passe solides et limiter les tentatives filtrer les exécutions PHP dans les dossiers non prévus, selon la configuration de votre hébergeur
Je privilégie aussi une politique de plugins: moins il y en a, moins il y a de chemins d’entrée. Le compromis, c’est la fonctionnalité. Mais un plugin non maintenu ou inconnu vaut rarement le risque.
Ce que je ferais si je devais recommencer à zéro sur un site touché
Pour rendre ça plus concret, je vous décris un déroulé “réflexe” que j’utilise quand la situation est floue, mais que je sais que la compromission touche wp-content.
J’élimine d’abord l’incertitude. Je récupère une copie saine si possible, sinon je m’appuie sur les versions officielles de chaque thème et plugin. Je remplace les composants suspects plutôt que de les corriger ligne par ligne. Ensuite, je regarde la base de données sur les zones où WordPress stocke des comportements persistants, notamment cron et options. Enfin, je réactive progressivement, je teste, puis je surveille.
Cette séquence prend du temps, mais elle évite de “réparer” un problème qui n’a pas de fin.
Points d’attention pour éviter les erreurs fréquentes
Il y a quelques pièges classiques qui font perdre des heures, ou pire, qui laissent une porte ouverte.
Premier piège: supprimer un seul fichier sans inspecter les plugins et thèmes chargés. Un petit code dans wp-content peut déclencher des téléchargements ou des inclusions à distance.
Deuxième piège: restaurer seulement une partie du site. Si vous remettez des fichiers propres mais que la base contient encore des déclencheurs, l’injection peut repartir comme si rien n’avait été fait.
Troisième piège: nettoyer en production sans surveillance. Les scripts conditionnels peuvent s’activer plus tard, et vous risquez de ne pas voir la repousse avant qu’elle soit visible pour les visiteurs.
Le bon réflexe consiste à faire des vérifications, pas juste à “effacer”.
Si vous devez demander de l’aide: quoi fournir pour aller plus vite
Si vous travaillez avec un prestataire, ou si vous cherchez à confirmer votre hypothèse, vous gagnerez du temps en fournissant des éléments précis. Un diagnostic efficace ne demande pas seulement “le site est infecté”, mais des preuves.
Je vous conseille de rassembler:
- le chemin exact des fichiers suspects dans wp-content la date de modification et le contenu minimal des lignes incriminées des captures du comportement observé (redirection, injection de scripts, pages touchées) une copie de la base ou au moins des exports, si possible avant modifications des extraits des logs serveur, même partiels, autour du moment où l’incident a commencé
Ce sont ces données qui permettent d’identifier la source d’exécution et de valider la correction.
Une dernière idée importante: la confiance dans “ce qui est propre”
Après un incident, on a envie de se rassurer rapidement, par exemple avec un scan qui affiche “tout va bien”. Les scanners aident, mais ils ne remplacent pas une approche orientée exécution.
Le vrai critère de réparation, c’est quand:
- aucun nouveau fichier suspect n’apparaît le HTML livré ne contient plus de scripts anormaux les erreurs PHP liées au code injecté cessent la base ne contient plus de déclencheurs persistants le site reste stable après remise en ligne, sur plusieurs cycles
C’est moins spectaculaire qu’un clic “résolu”, mais c’est ce qui évite la seconde vague.
Si vous voulez, décrivez-moi votre cas en quelques lignes: quel fichier ou quel sous-dossier de wp-content a été modifié, si un plugin ou un thème précis a l’air compromis, et quel comportement le site a montré. Je peux vous proposer une démarche de correction plus ciblée, adaptée à ce que vous avez déjà trouvé.