Nettoyage malware WordPress : vérifier les formulaires d’upload et médias

Quand un WordPress est “infecté”, on pense d’abord à des scripts cachés dans des fichiers PHP, à des redirections bizarres, ou à des utilisateurs nouvellement créés. Dans la vraie vie, une partie des infections se propage par des chemins plus subtils, et souvent plus pratiques pour l’attaquant: les formulaires qui acceptent des uploads, l’interface de médias, ou des actions liées aux images et aux fichiers. Si vous ne regardez pas ces points, vous risquez de supprimer la porte d’entrée sans fermer toutes les fenêtres.

Cette stratégie part d’une idée simple: beaucoup de malwares WordPress s’accrochent au cycle “je téléverse un fichier”, “je traite ce fichier”, “je l’affiche”, puis “je persiste”. Les formulaires d’upload et la gestion des médias deviennent alors des vecteurs. Et c’est particulièrement vrai quand l’attaque n’a pas besoin de casser le cœur de WordPress, elle peut se contenter de tirer parti d’un plugin vulnérable, d’une configuration trop permissive, ou d’un mode d’upload détourné.

Je vais donc vous guider dans une vérification réaliste, celle que je fais quand j’ai une alerte, un site qui se défigure, ou des traces dans les logs. L’objectif n’est pas uniquement “trouver le fichier malveillant”, mais aussi comprendre comment le site a pu accepter ce fichier et pourquoi il s’est comporté ainsi.

Comprendre le rôle des médias dans une compromission

WordPress n’est pas seulement une page qui s’affiche. C’est une application qui gère des entrées, des droits, des traitements d’images, et des métadonnées. Quand quelqu’un téléverse un fichier, plusieurs étapes entrent en jeu.

Le fichier arrive depuis un navigateur. WordPress ou un plugin valide le type, puis dépose le fichier quelque part sur le serveur. WordPress génère des dérivés, notamment des miniatures. Le contenu et les métadonnées sont enregistrés en base. Un rendu plus tard peut exécuter quelque chose si le fichier est interprété comme du code, ou si des chaînes malveillantes finissent réinjectées ailleurs.

C’est là que les “formulaires d’upload et médias” deviennent un terrain de chasse. Même quand l’attaque ne dépend pas d’une exécution immédiate, elle peut installer un mécanisme de persistance via des uploads, des thèmes, https://gardewp.fr/nettoyage-malware-wordpress/ des fichiers temporaires, ou des comportements de traitement.

Une anecdote typique: j’ai déjà vu des sites où la compromission commençait par une image “banale”. Le fichier portait une extension autorisée, mais le contenu avait une structure qui, combinée à une configuration serveur ou un traitement spécifique (par exemple une règle de type MIME), permettait de déclencher une exécution dans un autre endroit. Résultat, côté utilisateur, tout ressemblait à un média. Côté logs et arborescence, on voyait ensuite des fichiers créés à des endroits pas habituels, parfois avec des noms ressemblant à des hashes.

Ce qu’il faut surveiller côté formulaires d’upload

La plupart des gens contrôlent les fichiers PHP modifiés. C’est indispensable, mais ce n’est pas suffisant. Il faut vérifier aussi pourquoi et comment quelqu’un a réussi à passer la validation d’upload.

Les formulaires d’upload existent à plusieurs endroits dans l’interface WordPress. Il y a l’ajout de médias dans l’éditeur, le sélecteur de médias, la section Médias, et aussi des uploads déclenchés par des plugins (galeries, formulaires front, export/import, builders). Tous ne sont pas “le même chemin technique”, mais ils aboutissent souvent à la même logique côté WordPress: un point de réception, une validation, un dépôt, puis un enregistrement.

Ce que je cherche concrètement:

    Des tentatives d’upload après création d’une session suspecte, ou juste après un changement de droits. Des requêtes répétées sur des endpoints liés à l’upload (là où les médias sont déposés). Des fichiers déposés dont les extensions ne correspondent pas à ce que l’interface propose habituellement. Des métadonnées et enregistrements en base qui indiquent des médias “anormaux” (taille incohérente, nom étrange, date de création alignée sur un pic de trafic, URL interne utilisée ailleurs).

Un signal d’alerte fréquent, c’est la présence d’objets médias nouvellement créés avec des noms qui ressemblent à des fragments de code encodés, ou des variantes qui trompent des filtres simples. Si votre site a enregistré plusieurs médias sur une courte fenêtre, à une heure où personne ne travaille, c’est souvent une piste beaucoup plus rentable que de “tout re-scanner au hasard”.

Première étape: recouper les traces avant de toucher aux fichiers

Avant de supprimer des fichiers, je recommande presque toujours de faire un recoupement rapide entre logs, base de données et arborescence. Sinon, vous risquez de supprimer sans comprendre, et vous perdrez des éléments utiles pour attribuer la méthode d’entrée.

image

    Si vous avez accès aux logs web (Nginx, Apache) et aux logs PHP, cherchez des pics autour de l’heure supposée de l’infection. Recherchez dans les logs les endpoints qui reçoivent les uploads, et notez les IP, les user-agents, et surtout les séquences d’actions (upload, puis accès à des pages sensibles, puis modifications). Côté base, regardez les entrées récentes dans les tables liées aux médias (et pas seulement la table des utilisateurs). Les dates d’insertion et les identifiants peuvent donner des indices.

Dans une enquête réelle, j’ai souvent constaté que les fichiers “malveillants” n’étaient pas forcément ceux qui ont causé le dommage initial. Parfois, le premier dommage vient d’un plugin vulnérable qui a permis d’upload, puis la persistance se fait ailleurs. D’où l’intérêt de remonter le fil.

Vérifier l’accès aux uploads: droits, rôles, et endpoints

Un malware qui passe par les médias a généralement un moyen d’obtenir un contexte assez puissant. Il ne suffit pas que l’upload soit possible, il faut aussi que l’attaquant puisse le faire de manière répétée, ou assez discrète pour ne pas être bloqué.

Vérifiez d’abord les rôles WordPress et l’historique des utilisateurs:

    Les comptes créés récemment. Les comptes ayant changé de rôle. Les sessions dont vous ne reconnaissez pas le comportement.

Ensuite, côté configuration, regardez ce qui rend l’upload plus facile. Sur un site mal sécurisé, des plugins peuvent exposer des formulaires publics d’upload, ou accepter des fichiers sans restriction stricte. Par exemple, un formulaire de “soumission d’image” avec une validation légère côté front, puis une validation insuffisante côté serveur. Ou encore un plugin qui expose un champ “URL” pour importer une image et qui télécharge ensuite sans assez contrôler.

C’est souvent là que la logique “nettoyage malware WordPress” prend un virage pratique. Au lieu de partir sur une suppression massive, on identifie le vecteur exact, puis on corrige la cause.

Les “formulaires d’upload” ne sont pas seulement l’interface WordPress

Beaucoup d’attaques passent par un plugin, un thème, ou un script custom. Je pense notamment aux:

    constructeurs qui intègrent des “médias” côté front, galeries alimentées par des soumissions utilisateurs, plugins de facturation, réservation, ou “portfolio” qui permettent d’ajouter des pièces jointes, scripts d’import qui récupèrent des images distantes.

Même si vous nettoyez WordPress et que vous ne voyez plus de fichier PHP suspect dans wp-content/uploads, l’attaque peut continuer si la surface d’entrée n’a pas été corrigée.

Contrôler l’arborescence des médias: ce qui est normal et ce qui ne l’est pas

Le dossier wp-content/uploads/ est souvent l’endroit le plus “visible”. Mais attention: l’attaquant peut déposer ailleurs, notamment dans des sous-dossiers temporaires, des répertoires de cache, ou des emplacements liés à des thèmes et plugins.

Je procède généralement en trois couches.

Première couche, sur le dossier uploads: repérer des fichiers récents, inhabituels, ou dont l’extension ne “colle” pas au comportement attendu. Par exemple, la présence de fichiers PHP, JS, ou de fichiers dont le contenu ressemble à du code, alors que l’interface d’upload censée n’aurait accepté que des images ou des PDF.

Deuxième couche, sur les sous-dossiers: les attaques jouent parfois sur la structure. Si un sous-dossier uploads/2024/05/ a été créé récemment avec un grand nombre d’éléments, mais sans cohérence avec votre usage normal, c’est une piste.

Troisième couche, sur les répertoires de plugins et de thèmes: certains malwares ajoutent des loaders qui s’appuient sur les médias. On peut ne trouver aucune “charge” dans uploads, mais une logique dans un plugin détourné qui scanne des fichiers et les exécute plus tard.

Ce qui m’a appris la prudence, c’est que supprimer des fichiers au hasard peut casser votre site si des images légitimes ont été déplacées ou si des dépendances internes s’appuient sur des médias. Sur un chantier sérieux, je préfère d’abord cartographier, puis supprimer en mode ciblé.

Vérifier les fichiers qui ont été uploadés et comment ils sont servis

Quand on parle de “formulaires d’upload”, il faut aussi vérifier le traitement côté serveur web: comment Apache ou Nginx sert les types, et comment PHP interprète ou non certains fichiers. Un mauvais paramétrage peut transformer un fichier uploadé en exécutable, même si WordPress a essayé de limiter.

Sans entrer dans une configuration spécifique à votre hébergeur, je me concentre sur un point: un fichier “dans uploads” ne devrait jamais être interprété comme du PHP. Si vous constatez un comportement inattendu, la correction dépendra de votre stack (réglages PHP handler, règles de type, directives serveur).

Concrètement, après un upload suspect, je vérifie:

    les extensions déposées, les types MIME déclarés et réellement servis, si le fichier est accessible via URL et si cela déclenche une réponse qui ressemble à une exécution (code renvoyé, erreurs PHP, output étrange), si des fichiers sont “transformés” par un traitement dynamique (par exemple un script qui lit un fichier et renvoie son contenu).

Dans un cas où je faisais le tri, on avait des images avec des noms plausibles, mais leur réponse HTTP ne correspondait pas à des binaires d’image. Le navigateur affichait peut-être une image ou un message visuel trompeur, mais le serveur renvoyait quelque chose d’autre. Ce recoupement entre ce que WordPress croit avoir enregistré et ce que le serveur renvoie est souvent déterminant.

Inspecter la base de données: médias enregistrés, contenus associés, et métadonnées

Les malwares adorent les métadonnées parce que c’est là que WordPress relie un “média” à un contenu, un article, un bloc, ou un éditeur. Un fichier peut être présent sur le disque mais ne rien faire tant qu’il n’est pas référencé. À l’inverse, il peut être référencé sans être immédiatement dangereux, mais utile à une étape suivante.

Ciblez les enregistrements récents de médias et les liens vers des contenus. Sans faire de promesse sur les noms exacts des tables selon votre version, le principe est le même: les médias ont une entrée, et les contenus peuvent référencer ces médias.

Deux choses à rechercher, en pratique:

    Des médias récemment ajoutés qui ont des chemins d’accès ou des noms incohérents. Des articles ou pages modifiés récemment qui référencent ces médias, ou qui ont des blocs contenant des structures suspectes.

J’ai vu des cas où l’infection était “dans la page”, pas dans un fichier PHP. L’attaquant ajoutait un bloc ou un contenu qui déclenchait une récupération de fichier depuis uploads. En supprimant seulement les fichiers, on laissait en place une mécanique qui cassait ensuite le rendu ou renvoyait des erreurs. Inversement, supprimer des références sans corriger le vecteur d’upload laissait la porte ouverte.

Corriger la cause: validation d’upload et plugins concernés

Une fois que vous avez identifié le vecteur, la correction doit aller au-delà du nettoyage. Sur beaucoup de sites, le problème vient d’un plugin ou d’une configuration.

Le bon réflexe est d’isoler le périmètre: quels plugins utilisent l’upload, quels formulaires acceptent des fichiers, et lesquels étaient récemment mis à jour ou récemment installés. Un plugin ajouté il y a deux jours peut être la source. Un plugin ancien mais jamais durci peut aussi l’être, surtout s’il utilise une validation faible côté serveur.

Je conseille de:

    mettre à jour le cœur WordPress et les plugins présents, désactiver temporairement les plugins qui touchent aux uploads si vous devez enquêter, vérifier les paramètres de sécurité liés aux médias, et renforcer la validation côté serveur quand c’est possible.

Il y a un compromis à avoir en tête: trop restreindre peut casser des uploads légitimes. Trop permissif, et vous recréez un boulevard pour l’attaquant. Je vise généralement la restriction “utile” pour votre usage réel: extensions nécessaires, taille max cohérente, et types vérifiés au-delà de l’extension.

Procéder au nettoyage sans casser le site

Après l’analyse, vient la phase d’exécution. Ici, la méthode est plus importante que la brutalité.

Je recommande de travailler avec des copies et un plan de rollback. Idéalement, on effectue les changements en mode maintenance, ou au moins pendant une fenêtre de faible trafic. On commence par contenir.

Ensuite, on cible. Un malware lié aux uploads peut laisser:

    des fichiers en uploads/ à supprimer, des modifications dans wp-content/ ailleurs, des modifications dans des plugins ou thèmes, et parfois des entrées en base à nettoyer.

Le plus délicat, ce sont les fichiers médias. Supprimer un média légitime par erreur peut coûter du temps, surtout sur un site éditorial. Par prudence, je prends le temps d’ouvrir et de “comprendre” un fichier suspect avant de le supprimer, au moins en lisant un extrait et en observant ce que renvoie l’URL.

Pour les fichiers PHP ou scripts dans des emplacements non attendus, je suis plus direct. Mais même là, je sauvegarde et je vérifie que je ne supprime pas une dépendance nécessaire à un composant.

Durcir l’upload après correction: réduire la surface d’entrée

Une fois le nettoyage malware WordPress fait, le travail continu est de réduire la probabilité que ça recommence. Les formulaires d’upload et la gestion des médias sont souvent là où la sécurité se gagne ou se perd.

Je garde toujours deux lignes directrices. D’abord, rendre impossible ce qui n’est pas nécessaire. Ensuite, compliquer la répétition sans casser l’expérience.

Voici une courte checklist opérationnelle, celle que j’utilise pour vérifier rapidement le chemin des médias après incident:

    vérifier les plugins qui permettent l’upload côté front, et contrôler leurs réglages de type et taille autorisés s’assurer que seules les extensions nécessaires sont acceptées, et que le contrôle ne dépend pas uniquement de l’extension contrôler les fichiers déposés récemment dans wp-content/uploads/ par date et par nom, en excluant ce que vous utilisez réellement réviser les rôles et permissions, et limiter au strict nécessaire la capacité d’ajouter des médias mettre en place une surveillance sur les événements d’upload, au moins en logs, pour repérer un pic anormal

Cette liste n’est pas une formule magique, mais elle couvre les points où un incident se répète le plus souvent.

Cas pratiques: symptômes qui pointent vers les médias

Les infections ne se ressemblent pas, mais certains symptômes orientent vers les formulaires d’upload.

Sur un site compromis via uploads, vous pouvez observer:

    des médias ajoutés sans action de l’équipe éditoriale, des pages qui changent de façon étrange, parfois après la création d’un article qui référence un média, des redirections qui semblent liées à des fichiers accessibles via URL, des erreurs sporadiques lors de l’édition médias ou lors de l’affichage de certaines pages.

J’ai aussi vu des situations où le site ne “semble” pas cassé. L’attaquant utilise les uploads comme réserve, puis active une autre étape plus tard. Dans ce scénario, le nettoyage qui cible seulement le front ne suffit pas. Il faut précisément inspecter ce qui a été déposé.

Pièges fréquents pendant la vérification

Il existe quelques pièges qui m’ont fait perdre du temps au début, ou que je vois encore aujourd’hui chez des équipes expérimentées.

Premier piège: se contenter de scanners PHP classiques. Oui, ils détectent des scripts modifiés. Mais si la compromission réside dans la manière dont les médias sont traités, le scan de signature peut être incomplet.

Deuxième piège: supprimer sans comprendre le rôle d’un fichier. Un média peut être “suspect” de par sa taille ou son nom, mais il est parfois utilisé dans un bloc valide. Si vous supprimez en aveugle, vous créez un nouvel incident: une mise en page cassée, ou des pages en erreurs.

Troisième piège: ne pas corriger le vecteur. Après nettoyage, si le formulaire d’upload reste exploitable, la compromission reviendra, parfois avec une variante. Résultat, vous vous retrouvez dans un cycle “nettoyer, re-nettoyer, re-nettoyer”, ce qui épuise plus qu’il ne sécurise.

Quatrième piège, plus technique: confondre un fichier “accessoire” et une “charge”. Un malware peut déposer des fichiers de leurre dans uploads, et garder la charge ailleurs. Se focaliser seulement sur uploads peut alors être insuffisant.

Une méthode de triage rapide en cinq décisions (sans liste d’inventaire)

Je vous propose une manière de raisonner, très concrète, qui évite de tomber dans l’accumulation.

D’abord, trouvez ce qui a changé récemment. Si vous avez des logs, vous identifiez une fenêtre. Si vous n’en avez pas, vous regardez les dates de modification des fichiers et les dates de création dans la base pour les médias et contenus. C’est souvent assez pour circonscrire.

Ensuite, cherchez les entrées qui ont un lien avec les uploads. Par exemple, des médias ajoutés, puis des contenus modifiés ensuite. La chronologie raconte plus que beaucoup d’outils.

Troisièmement, inspectez les médias déposés qui sortent du lot. Un média “suspect” n’est pas forcément un .php. Cela peut être un fichier avec extension acceptable, mais un contenu inattendu. L’idée est de comparer ce que vous observez avec ce que vous attendez d’un usage normal.

Quatrièmement, identifiez comment un upload a pu être accepté. Cela implique de vérifier les plugins et les formulaires front, pas seulement les réglages WordPress de base.

Enfin, corrigez la cause, puis seulement après, restaurez un état propre. Cette séquence évite de corriger le symptôme, puis d’être attaqué de nouveau pendant que vous terminez le nettoyage.

Après incident: vérifier que le site n’est plus exploitable via médias

Quand le nettoyage est terminé, il faut valider. Pas avec un scan qui “dit” tout est OK. Avec une vérification de comportement.

Je veux m’assurer que:

    la surface d’upload n’accepte plus ce qui était accepté par erreur, les uploads ne créent plus de fichiers anormaux, les médias ajoutés légitimement fonctionnent, et les endpoints d’upload ne déclenchent plus d’actions suspectes.

Voici une deuxième mini-checklist, orientée validation, qui tient sur une page mentale:

    tester l’upload d’un fichier autorisé (image ou PDF, selon votre politique) et confirmer le comportement de bout en bout vérifier que les types, tailles, et extensions refusés sont bien rejetés côté serveur contrôler que la base enregistre uniquement des médias attendus après un upload légitime surveiller les logs pendant une période courte, par exemple quelques heures, après validation vérifier l’éditeur médias et la création d’articles, pour s’assurer qu’aucun bloc ou référence suspecte n’est réapparue

Cette étape est souvent celle qui manque, et c’est elle qui révèle si une correction est vraiment efficace.

Ce que j’envisage toujours en dernier recours: l’approche “réinstallation maîtrisée”

Dans certains cas, notamment quand l’accès a été très profond ou quand trop de fichiers ont été modifiés, on arrive à un point où la réinstallation maîtrisée devient plus fiable qu’un patchwork. Ça ne veut pas dire “tout supprimer en vitesse”.

L’approche que je privilégie quand la situation est ambiguë consiste à:

    conserver une sauvegarde datée, restaurer le noyau WordPress et les dépendances de manière propre, reconstruire l’ensemble à partir de versions validées, puis intégrer vos thèmes, plugins et médias de manière contrôlée.

Le point clé est de ne pas réimporter un vecteur. Si le problème venait d’un plugin d’upload vulnérable, le réinstaller sans correction ferait revenir l’incident.

Je mentionne cette option parce qu’elle existe, et qu’elle permet de sortir du cycle de nettoyage quand les preuves s’accumulent sans qu’on arrive à isoler proprement la cause.

Conclusion de travail: sécuriser l’upload, c’est sécuriser la porte d’entrée

Quand on parle de nettoyage malware WordPress, on se concentre souvent sur ce qui est “évident” dans les fichiers. Mais les formulaires d’upload et la gestion des médias sont une porte d’entrée concrète, parce qu’ils sont conçus pour accepter ce qui vient de l’extérieur. C’est utile pour un site. C’est aussi exploitable si la validation, les permissions, ou les plugins ne sont pas à la hauteur.

Si vous ne vérifiez que la surface PHP, vous risquez de fermer l’entrée principale sans empêcher la prochaine tentative. Si vous combinez analyse chronologique, inspection des médias déposés, et correction du vecteur (plugins, endpoints front, règles serveur, permissions), vous transformez un nettoyage ponctuel en reprise durable.

Et la meilleure preuve de réussite, dans ce genre d’incident, reste la même: l’upload redevenu un acte normal, sans traces anormales, sans créations fantômes, et sans comportement inattendu côté serveur.

image

Si vous voulez, dites-moi votre configuration (hébergeur, Nginx ou Apache, plugins d’upload ou formulaires front utilisés, et ce que vous avez observé côté médias). Je peux vous https://gardewp.fr/ proposer une trajectoire de vérification plus ciblée, adaptée à votre cas.