Sécurité WordPress : prévenir l’upload de scripts malveillants

Sur un site WordPress, il y a une différence nette entre “avoir un problème” et “s’en rendre compte assez tôt”. L’upload de scripts malveillants fait partie de ces risques où le dommage peut être discret au début. Le fichier arrive, il ne “fait” rien tout de suite, puis il est exécuté à la première requête, ou bien il sert de passerelle à autre chose, comme l’exfiltration de données ou l’installation d’un second niveau de compromission.

Ce qui rend le sujet délicat, ce n’est pas uniquement la présence de tentatives d’upload. C’est surtout la combinaison de facteurs qui autorisent un script à passer entre les mailles: permissions d’écriture trop larges, configuration serveur permissive, validation de type de contenu insuffisante, rôles mal gérés côté administration, et parfois une hygiène d’audit trop rare. Renforcer sécurité WordPress, ce n’est pas “tout bloquer”. C’est construire un système où l’upload est autorisé uniquement là où il doit l’être, et où un fichier suspect ne peut pas devenir exécutable.

Comprendre le chemin d’un script après un upload

Quand quelqu’un “upload” sur WordPress, il ne s’agit pas forcément de l’acte final. Le script doit, ensuite, trouver un chemin pour être accessible et interprété.

Dans beaucoup de cas réels, l’attaque passe par un scénario assez banal:

image

    un compte compromis (mot de passe réutilisé, cookie volé, session laissée active, plugin vulnérable) ou un point d’entrée qui permet de déclencher un upload sans être un administrateur légitime puis l’envoi d’un fichier déguisé (extension trompeuse, nom de fichier manipulé, contenu ne correspondant pas au MIME annoncé)

La seconde étape est souvent la plus dangereuse. Le fichier doit se retrouver dans un répertoire accessible via le web et, surtout, traité par le bon interpréteur. Un exemple classique: uploader un fichier qui “ressemble” à une image mais contient un code exploitable, et espérer que le serveur l’exécutera comme du PHP.

image

À ce stade, tout dépend de votre architecture. Si votre hébergement est configuré pour ne jamais exécuter de code dans les répertoires d’uploads, le même fichier deviendra souvent un simple fichier téléchargeable, pas une exécution. C’est pour ça qu’une bonne stratégie combine plusieurs barrières. Si l’une échoue, les autres ralentissent, ou empêchent complètement l’impact.

Les endroits où WordPress accepte (et où l’attaquant vise)

WordPress n’est pas un système d’upload monolithique. Il existe plusieurs chemins. Le plus évident est la médiathèque et le répertoire de destination des uploads, souvent quelque chose comme wp-content/uploads/ avec des sous-dossiers par mois. Mais il existe aussi des uploads “indirects”: plugins, thèmes, fichiers importés, ou scripts générés par certains outils d’administration.

L’objectif pour un attaquant est généralement le même, obtenir un emplacement web accessible où l’interpréteur risque d’être activé. Les réglages exacts varient selon votre serveur (Apache, Nginx, configurations manuelles), mais l’idée reste identique: rendre la ressource https://gardewp.fr/securite-wordpress/ non exécutable et limiter ce qui peut entrer.

Un point à ne pas négliger: même si le serveur est bien configuré, un fichier malveillant peut parfois servir comme outil de reconnaissance ou de persistance. Il suffit qu’il soit listable, téléchargeable, ou exploitable via un autre vecteur (par exemple une vulnérabilité de lecture de fichiers ailleurs). Donc “bloquer l’exécution” est essentiel, mais il faut aussi réduire la probabilité qu’un fichier passe.

Ce qui autorise l’upload de scripts malveillants

Il y a des causes qu’on voit encore trop souvent sur des sites pourtant “correctement maintenus”.

Permissions et droits trop généreux

Si un processus serveur peut écrire plus largement que nécessaire, un intrus dispose de plus d’angles. Un WordPress bien isolé n’a pas besoin que tout soit en écriture au même endroit. Sur le plan pratique, on vise le principe de moindre privilège: les répertoires indispensables à l’upload doivent être en écriture, et le reste non.

Quand c’est trop large, on ne parle plus seulement d’upload. On parle aussi de modifications d’autres fichiers, ce qui change l’impact.

Validation de fichier: il ne suffit pas de bloquer “l’extension”

Beaucoup de sites ont une règle simple du type “interdire les fichiers .php”. C’est utile, mais ce n’est pas suffisant à lui seul. Les attaquants ont plusieurs façons de contourner une logique naïve:

    double extension, ou noms ambigus présence de contenu qui n’est pas une image, mais une charge utile envoi d’un type MIME trompeur côté requête

Et côté WordPress, attention à un point de friction courant: la validation du type peut être influencée par des réglages PHP, par la chaîne de traitement, et par des filtres installés. Vous voulez une validation cohérente, robuste, et testée avec vos types de médias légitimes.

Rôles, mots de passe et sessions

Même avec une bonne configuration, si un compte ayant le droit d’upload est compromis, l’attaquant tentera sa chance. On observe souvent des habitudes de gestion des mots de passe, ou des sessions ouvertes depuis longtemps, surtout sur les sites qui ont peu d’accès administrateur.

La sécurité ne se résume pas à “empêcher un upload”. Elle inclut le fait d’empêcher qu’une personne non autorisée puisse réaliser un upload en premier lieu.

Renforcer sécurité WordPress, au quotidien: des barrières à plusieurs niveaux

Je préfère raisonner en couches. Une couche ne doit pas être “le plan”. Elle doit être une barrière.

1) Bloquer l’exécution dans les répertoires d’uploads

Même si un fichier arrive, votre objectif est que le serveur ne l’exécute pas.

Sur Apache, l’approche typique consiste à désactiver l’exécution de scripts dans wp-content/uploads (et éventuellement dans d’autres répertoires d’upload). Sur Nginx, on peut configurer un location qui empêche l’envoi vers un interpréteur PHP dans ces chemins. Sur des environnements spécifiques, le fournisseur d’hébergement peut proposer une règle prête à l’emploi, et c’est souvent plus sûr que bricoler sans contexte.

Le piège: une règle trop agressive peut casser des usages légitimes, par exemple si vous servez des fichiers générés par certains outils qui s’appuient sur un interpréteur. C’est rare pour des uploads “standards”, mais ça arrive avec des intégrations particulières. Dans le doute, testez sur un environnement de préproduction et vérifiez le comportement avec vos médias.

2) Appliquer une validation côté WordPress, pas seulement côté serveur

Le serveur protège la partie “exécution”. WordPress peut aider à la partie “admission”. L’idée est simple: limiter ce qui peut être importé via l’interface WordPress, et refuser ce qui ne correspond pas à vos besoins réels.

En pratique, cela se traduit par:

    limiter les extensions acceptées (et pas seulement le MIME annoncé) vérifier le type réel quand c’est possible empêcher l’accès direct aux fichiers qui ne correspondent pas à ce que WordPress attend

Selon vos besoins (PDF, SVG, images, vidéos), vous devrez affiner. Là où je vois le plus d’erreurs, c’est sur SVG. Beaucoup de sites activent SVG sans comprendre le risque. Un SVG est un fichier XML, donc un format qui peut contenir des choses inattendues s’il n’est pas nettoyé. Si vous avez besoin de SVG, il faut un traitement ou une sanitation sérieuse, pas juste “autoriser l’extension”.

3) Protéger le chemin d’accès: limiter qui peut uploader

Même une validation parfaite ne compensera pas un compte administrateur compromis. C’est souvent là que les incidents démarrent.

Quelques ajustements qui changent vraiment le risque:

    appliquer le principe du moindre privilège sur les rôles (un auteur n’a pas à être éditeur, un éditeur n’a pas besoin d’admin) supprimer les comptes inutilisés verrouiller le contrôle d’accès aux actions sensibles renforcer la gestion des identifiants, notamment contre la réutilisation

On peut aussi réduire la surface en limitant les utilisateurs ayant la capacité de téléverser des fichiers. Sur certains sites, le plus simple est de rendre l’upload indisponible pour la majorité des utilisateurs, et de centraliser les ajouts via un flux contrôlé.

Les signaux d’alerte à surveiller après un upload

Un upload malveillant laisse souvent des traces. Parfois ce n’est pas une preuve directe, mais un ensemble d’indices cohérents.

Voici les signaux que je surveille en priorité sur des sites touchés ou “à risque”, car ils ont tendance à précéder l’impact:

    des fichiers fraîchement créés dans wp-content/uploads avec des noms anormaux, des tailles atypiques pour vos médias des tentatives répétées d’accès à des URLs qui ressemblent à des scripts, parfois avec des extensions déguisées des pics de 404 et de 403 sur des chemins inhabituels, surtout juste après une période de tentatives d’identification des erreurs PHP dans les logs liés à un contenu inattendu, même si le site ne “crashe” pas des comptes dont les sessions ou les actions ont eu lieu alors que personne ne travaillait sur le site

Aucun de ces signaux, seul, ne suffit. Mais quand plusieurs apparaissent ensemble, vous avez une piste concrète. Et plus tôt vous regardez l’arborescence et les requêtes associées, plus il devient facile de confirmer ce qui a été uploadé.

Concrètement, comment réduire le risque d’upload et d’exécution

Il y a une différence entre “je bloque tout ce qui ressemble à un script” et “je construis une règle qui tient dans la durée”.

Sans tomber dans l’obsession, je vous recommande de vérifier trois axes: admission (est-ce que WordPress accepte?), stockage (où arrive le fichier?), exécution (le serveur l’interprète-t-il?).

Les réglages qui font la différence côté serveur

La plupart des bonnes mesures côté serveur se jouent sur:

    la manière dont le serveur traite les fichiers dans wp-content/uploads l’isolation de PHP-FPM ou du module PHP l’absence de mappage interprétatif dans les répertoires d’uploads

Je préfère utiliser des solutions adaptées à votre stack hébergement, parce que les variantes existent. Certains hébergeurs ont déjà des règles “anti-exécution dans uploads”. Si vous les avez, mieux vaut les activer plutôt que réécrire une config maison.

Les filtres WordPress: attention à l’effet de bord

Activer des filtres “anti-mime” trop stricts peut casser des formats légitimes. J’ai vu des sites qui bloquaient des images WebP, ou qui modifiaient des PDFs importés. Le bon réflexe consiste à définir une liste réaliste de formats autorisés pour votre site, puis de tester.

Ce n’est pas seulement une contrainte technique, c’est aussi une contrainte opérationnelle. Si vous bloquez trop, vous augmentez la friction et les contournements finissent par apparaître, par exemple upload via un outil externe ou contournement “par nécessité”.

Les plugins de sécurité: utiles, mais pas un bouclier unique

Les plugins peuvent aider à:

    filtrer les types de fichier détecter des patterns d’upload renforcer l’accès admin

Le piège, c’est de considérer qu’un plugin “résout” le sujet à lui seul. Quand on installe un plugin, on change la logique. Parfois un filtre se désactive sur une route spécifique, ou une exception est ajoutée. Le remède n’est pas de refuser les plugins, c’est de les intégrer à une stratégie cohérente, et de vérifier le comportement réel sur votre site.

Une configuration de référence: ce que j’attends d’un site bien protégé

Plutôt que de promettre une règle universelle, je décris ce que je considère comme une base solide. L’objectif est de rendre l’upload de scripts plus difficile et surtout moins utile une fois arrivé.

    Répertoires d’uploads non exécutables, même si un fichier malveillant y arrive Validation admission cohérente (type, extension, contenu quand possible) sans casser vos médias Droits minimaux, pas de comptes “en trop” ni de rôles surpuissants Journalisation exploitable (logs serveur et traces applicatives), pour repérer rapidement une anomalie Process d’audit régulier, sinon vous ne voyez pas ce qui change

Ce socle réduit drastiquement le risque d’impact. Et surtout, il rend l’attaque moins rentable, ce qui est la vraie logique de la sécurité.

Checklist pratique pour passer à l’action (sans casser votre site)

Voici une approche pragmatique, orientée “résultat”, pas “théorie”. Je l’utilise comme guide interne avant des modifications.

Faites l’inventaire de vos formats réellement utilisés (images, PDF, documents, médias vidéo, SVG si présent). Vérifiez la configuration serveur: les chemins d’uploads doivent refuser l’exécution côté PHP. Ajoutez ou ajustez une validation côté WordPress, en ciblant extension, type et contenu selon votre stack. Nettoyez l’accès: retirez les comptes inutilisés, réduisez les rôles, et imposez des pratiques d’authentification solides. Activez une surveillance des logs et planifiez un audit périodique des fichiers récents dans uploads.

Si vous devez choisir, commencez par l’exécution dans uploads. C’est souvent la barrière la plus efficace, parce qu’elle neutralise le scénario “le fichier arrive puis devient script”.

Scénarios d’attaque à anticiper (et compromis à accepter)

Un point important: votre réponse doit tenir compte des scénarios plausibles. Par exemple, si vous autorisez l’upload de PDF pour des formulaires, vous allez gérer des fichiers dont le contenu binaire n’est pas “lisible” pour une simple règle d’apparence. Une validation trop dure peut entraîner des faux positifs. À l’inverse, si vous autorisez SVG, vous devez accepter le coût de la sanitization et des contrôles additionnels.

image

Autre scénario: un site qui a besoin d’importer des médias depuis des URL externes. Dans ce cas, la “source” n’est pas l’upload manuel. Un attaquant peut tenter d’empoisonner le contenu. La validation doit donc s’appliquer aussi à l’import et pas seulement au formulaire de téléversement.

Enfin, edge case fréquent: certains outils tiers écrivent dans uploads pour générer des ressources. Si votre règle bloque tout ce qui ressemble à un script, elle doit aussi ne pas bloquer ces usages légitimes. D’où l’importance de tester, et de documenter les changements.

Tester que la protection fonctionne vraiment

Une règle qui “a l’air” bonne ne veut rien dire si vous ne validez pas.

Le test, c’est:

    confirmer que les fichiers uploadés depuis l’interface sont acceptés pour les formats légitimes confirmer qu’un fichier suspect ne peut pas être exécuté, même si le navigateur y accède observer les logs pour vérifier qu’il y a un blocage ou au moins une neutralisation

Je recommande d’impliquer votre environnement de préproduction quand c’est possible, ou à minima un sous-domaine de test. Les erreurs de configuration serveur peuvent produire des conséquences inattendues, par exemple des 404 sur les médias.

Aller plus loin: organisation et maintenance

La sécurité n’est pas un réglage unique. Elle vit dans le temps.

Un bon réflexe consiste à:

    garder une visibilité sur les fichiers récents et les modifications dans WordPress appliquer les mises à jour en maîtrisant les impacts (ne pas seulement “mettre à jour”, mais vérifier que les uploads et les médias fonctionnent ensuite) maintenir une hygiène de compte (mots de passe, suppression des comptes obsolètes, revue des utilisateurs)

Renforcer sécurité WordPress, c’est aussi clarifier qui a le droit d’agir. Sur les sites qui ont “beaucoup de monde” côté contenu, la gouvernance devient aussi importante que la technique. Si l’accès upload est trop ouvert, vos contrôles techniques seront toujours mis sous pression.

Si vous suspectez un upload malveillant: quoi faire rapidement

Si vous avez un doute, la vitesse compte, mais la précipitation peut aggraver. L’approche que je conseille est simple: confirmer, isoler, puis nettoyer proprement.

Commencez par identifier les fichiers créés récemment dans uploads, vérifiez leur extension, leur taille et leurs dates. Regardez ensuite s’il y a des tentatives d’accès dans les logs serveur. Si vous observez un comportement d’exécution, il faut prendre en charge l’incident comme une compromission potentielle et pas seulement comme un “fichier à supprimer”.

Même si vous supprimez un script, il faut traiter la cause: compte compromis, faille d’accès, plugin vulnérable, ou configuration permettant l’upload non autorisé. Sinon, le même scénario revient.

L’upload de scripts malveillants n’est pas un fantasme. C’est une opportunité opportuniste pour des attaquants, surtout quand les contrôles sont incomplets. La bonne stratégie combine une admission plus stricte, des droits d’accès mieux cadrés, et surtout une barrière serveur qui empêche l’exécution dans les répertoires d’uploads. C’est cette combinaison qui vous donne une marge, et qui transforme une tentative d’attaque en simple erreur sans impact.