Audit et sécurisation WordPress : vérifier la configuration des images et MIME types

Sur un site WordPress, les images semblent rarement “dangereuses”. Et pourtant, dans beaucoup de compromissions, le point de départ n’est pas un script exécuté dès la première page. C’est plutôt une surface d’attaque plus discrète: l’upload, la manière dont le serveur valide (ou non) le type de fichier, et la façon dont WordPress et la configuration web servent ces fichiers ensuite.

Quand on parle d’audit et sécurisation WordPress, la question des images et des MIME types revient presque systématiquement, surtout dès qu’on observe des erreurs bizarres, des fichiers déposés sans raison, ou des comportements confus comme des images qui ne s’affichent pas ou qui déclenchent des téléchargements inattendus. L’objectif n’est pas seulement de “corriger”, c’est de comprendre le chaînage complet: ce que WordPress autorise à l’upload, ce que le serveur déclare au navigateur via le header Content-Type, et ce qui est réellement envoyé sur le disque.

Le vrai rôle du MIME type, et pourquoi ça dépasse l’upload

Un MIME type, c’est une étiquette. Elle sert principalement à dire au navigateur comment interpréter le contenu. En pratique, deux choses peuvent diverger.

Première divergence possible: le fichier “ressemble” à une image, mais son contenu ne correspond pas, ou son entête est trompeur. Cela arrive avec des polygots, où le contenu peut être interprété de plusieurs façons selon les moteurs, ou simplement avec des fichiers malformés, renommés, ou volontairement trafiqués.

Deuxième divergence possible: la vérification côté WordPress ou côté serveur peut se baser sur le nom de fichier (extension) au lieu du contenu réel. Si l’extension est autorisée, le fichier passe à l’upload, même si le contenu ne devrait pas.

Troisième divergence possible: même si WordPress refuse à l’upload, un serveur peut ensuite servir le fichier avec un Content-Type inattendu, ou des règles de configuration peuvent faire varier le traitement selon les chemins (par exemple uploads vs fichiers temporaires), ou selon l’engine (Apache, Nginx, proxy devant).

Dans une sécurisation WordPress sérieuse, on ne se contente pas de vérifier “est-ce que c’est une image”. On vérifie aussi “qu’est-ce que le serveur croit envoyer” et “est-ce que le navigateur, ou un filtre en amont, l’interprétera comme du code”.

Pourquoi les images posent quand même un risque

Les fichiers image sont généralement “safe by default” quand tout est cohérent. Mais si vous cassez la cohérence, l’attaque devient réaliste.

Quelques scénarios typiques qu’on voit en audit:

Un formulaire d’upload accepté pour certaines extensions, alors que la validation réelle est faible. Résultat: un fichier non image entre quand même. Une configuration qui autorise un type de contenu trop permissif. Par exemple, un serveur qui associe une extension à un Content-Type qui permet l’exécution par un composant en aval. Des règles “automatiques” qui tentent de déduire le type à partir de l’extension, sans lecture fiable du contenu. Des cas particuliers comme SVG, où le fichier est techniquement un “document” (et souvent un texte XML), donc plus proche d’un contenu interprétable que d’une image raster.

Le point clé, c’est que l’image n’est pas l’ennemi. L’incohérence l’est: incohérence entre extension, entête, contenu, et header de réponse.

Comprendre le parcours d’un fichier dans WordPress

Avant de toucher à la config, je conseille de se représenter le parcours complet.

  1. L’upload passe par WordPress, qui vérifie les types autorisés (via la liste des extensions et souvent via des validations basées sur les données disponibles). 2) WordPress enregistre le fichier dans wp-content/uploads/ avec un nom, une date, et des métadonnées. 3) Le serveur web sert ce fichier. C’est à ce moment que Content-Type et les règles de traitement (cache, headers, interprétation) entrent en jeu.

En audit, beaucoup d’équipes se focalisent uniquement sur WordPress (plugins, réglages dans l’admin), puis constatent que rien ne change. La raison est simple: même si WordPress bloque l’upload, le serveur peut avoir des associations MIME faibles ou des règles de sécurité incomplètes sur la diffusion. À l’inverse, si WordPress laisse passer mais que le serveur force le type ou bloque l’exécution, le risque peut être réduit. Dans tous les cas, c’est la chaîne qui compte.

Où chercher les signaux faibles (sans partir dans l’angoisse)

Quand on suspecte un problème, je préfère une approche “preuve d’abord”. Elle évite de modifier la configuration au hasard, ce qui peut casser des formats légitimes.

Voici des indicateurs concrets qui justifient de pousser l’audit sur images et MIME types:

Des uploads non attendus dans wp-content/uploads/ (noms étranges, extensions peu habituelles, volumes). Des erreurs de lecture d’images par les navigateurs, suivies de téléchargements forcés. Des Content-Type incohérents observés côté navigateur ou via les headers HTTP (par exemple un fichier avec une extension image servi comme text/plain ou application/octet-stream). Des fichiers SVG présents dans des dossiers où vous n’en attendez pas. Une divergence entre ce qu’affiche WordPress et ce que répond le serveur (par exemple WordPress croit gérer un type, mais le serveur traite autrement).

Si vous combinez ces signaux avec les logs d’accès et les événements WordPress (selon votre pile d’observabilité), vous obtenez un cadre d’investigation solide.

Vérifier ce que WordPress autorise vraiment à l’upload

Dans un audit, la question “quelles extensions sont autorisées” est une évidence, mais elle ne suffit pas.

WordPress peut, selon la configuration et les filtres en place, accepter des types “image” à partir de sa liste autorisée. Cette liste dépend notamment du support des formats et des extensions. Le piège est que certains formats sont délicats à sécuriser, même s’ils sont “des images” à l’usage:

SVG: souvent accepté pour la qualité, mais plus risqué car c’est du XML pouvant contenir des références ou du contenu interprétable. WebP: généralement plus sûr car c’est un format binaire, mais il faut éviter les confusions si des conversions ou des proxys traînent. HEIC ou AVIF: parfois support dépendant des libs installées, et des serveurs peuvent échouer de façon partielle (ou servir avec un type inattendu).

Ce que je cherche, c’est la cohérence: si WordPress accepte un format, le serveur doit aussi le servir de manière raisonnable, et surtout pas le traiter comme du texte ou un script.

Contrôler le Content-Type côté serveur, pas seulement côté admin

C’est souvent l’étape qui fait la différence. Dans les audits que j’ai menés, on peut avoir “zéro alerte” dans l’admin, et pourtant le serveur renvoie des headers surprenants.

Concrètement, je recommande de tester avec un ensemble d’images représentatives:

Une image raster classique (JPEG ou PNG). Une image dans un format plus sensible si vous l’utilisez (WebP, éventuellement AVIF). Le cas échéant, un SVG de test, uniquement en environnement de recette.

L’idée n’est pas de “chercher un bug”, c’est d’établir une référence. Si un JPEG est servi comme image/jpeg, très bien. Si, au contraire, il ressort en text/plain, application/x-httpd-php ou autre combinaison étrange, il y a un problème d’association MIME côté serveur.

Le bon réflexe: utiliser les headers HTTP observables. Que vous passiez par l’inspecteur navigateur, curl, ou vos outils internes, l’objectif reste identique: vérifier Content-Type et, selon votre stack, Content-Disposition et headers de sécurité associés.

Cas particulier: SVG et les risques qui viennent de la nature du format

Les SVG sont souvent demandés parce qu’ils sont légers et nets. En sécurisation, c’est justement là que ça se complique. Un SVG n’est pas juste un “dessin”. C’est un document texte structuré.

Ce qui m’intéresse en audit, c’est:

Est-ce que votre pipeline autorise l’upload de SVG sans filtrage. Est-ce que le serveur sert ces fichiers avec les headers attendus. Est-ce que le navigateur interprète correctement le contenu et comment il le fait selon votre configuration de site.

Selon votre niveau d’exigence et votre risque acceptable, vous pouvez prendre une décision stricte: interdire SVG à l’upload, ou bien l’autoriser seulement après nettoyage côté application (ce qui revient à ajouter une étape de sanitization). Le compromis est réel: interdire SVG réduit la surface d’attaque mais casse certains usages. Autoriser sans traitement, c’est rarement un choix prudent.

Et surtout, si vous autorisez SVG, ne vous contentez jamais de regarder “ça s’affiche”. Vérifiez aussi ce qui est effectivement servi et comment il est interprété.

Les pièges classiques dans la configuration serveur

Selon que vous êtes sur Apache ou Nginx, la logique d’association MIME peut être différente, mais les erreurs de conception se ressemblent souvent.

Le piège numéro un: une association basée sur l’extension, sans cohérence avec le type réel. Résultat: un fichier avec une extension image est annoncé comme image, même si le contenu est autre https://gardewp.fr/securite-wordpress/ chose.

Le piège numéro deux: des règles de gestion d’emplacements. Par exemple, vous appliquez des protections sur un dossier, mais les uploads suivent un autre chemin via un alias, un symlink, ou une configuration de proxy. Vous pensez avoir sécurisé, mais la règle ne s’applique pas.

Le piège numéro trois: les conversions et traitements automatisés. Si vous redimensionnez, transcoderez, ou appliquez des transformations, le type final peut dépendre de la chaîne de traitement. Si une lib échoue partiellement, vous pouvez obtenir des sorties inattendues.

Dans un audit, j’ai tendance à faire un “contrôle de cohérence” simple: même test d’image, même URL, vérifier à la fois les headers et le comportement du navigateur. Si l’un des deux est atypique, la sécurité et la fiabilité sont en question.

Une méthode d’audit pragmatique, du plus simple au plus utile

J’aime bien organiser l’audit en “couches”, parce que l’on peut corriger sans casser. Le but est de sécuriser sans dégrader la diffusion des formats légitimes.

Petite grille de triage (avant de modifier quoi que ce soit)

Repérer les formats réellement utilisés sur le site (JPEG, PNG, WebP, SVG). Vérifier, sur un échantillon d’URL, les Content-Type renvoyés par le serveur pour chaque format. Regarder les extensions présentes dans wp-content/uploads/ et leur fréquence. Comparer WordPress (ce qui est accepté) et la réponse serveur (ce qui est servi). Consulter les logs d’accès liés aux uploads (surtout si des fichiers apparaissent “sans raison”).

Cette grille n’est pas un audit exhaustif. C’est un triage efficace, qui évite les corrections aveugles.

Sécuriser sans casser: décisions à prendre sur les MIME types

Une sécurisation réussie vient souvent d’un choix. Vous devez décider du niveau de strictness sur les uploads et sur la diffusion.

Le choix le plus fréquent est d’être strict côté upload: n’accepter que les formats nécessaires, et empêcher l’entrée de fichiers dont le contenu ne correspond pas. Ensuite, côté serveur, être strict sur la manière dont on sert ces fichiers.

Mais il y a des détails qui comptent:

Si vous bloquez trop agressivement les types, vous risquez des ruptures chez les visiteurs sur des navigateurs qui demandent certains formats. Si vous autorisez WebP sans contrôler la chaîne de conversion, vous pouvez obtenir des images non affichées ou servies comme type inattendu. Si vous autorisez SVG, le compromis doit inclure un mécanisme de sanitization, sinon vous donnez trop de latitude.

Dans mon expérience, le “bon” niveau de strictness dépend du contexte: audience interne ou public large, exposition à des uploads non authentifiés ou uniquement via comptes, niveau de risque global, et présence d’un WAF ou d’un proxy en amont.

Mesures de remédiation typiques (en gardant la main sur les exceptions)

Les actions ci-dessous ne sont pas une recette universelle, mais elles reflètent ce que j’ai vu fonctionner quand l’audit met en évidence une incohérence MIME, ou une surface d’upload trop large.

Restreindre les formats autorisés dans WordPress à ceux réellement nécessaires (en excluant ce qui pose problème, typiquement SVG si vous ne le traitez pas). Vérifier et corriger les associations MIME du serveur pour que les extensions image soient servies avec des Content-Type cohérents. Mettre en place des règles pour empêcher l’exécution de contenu dans les dossiers d’uploads (selon Apache ou Nginx). Ajouter une couche d’analyse côté application qui valide davantage que l’extension, notamment pour éviter les faux images.

Le point important est le “comment”. Si vous modifiez une config serveur, faites-le sur une recette, testez avec plusieurs formats réels du site, puis seulement après appliquez. Ce sont souvent les ajustements de dernière minute, pour “juste autoriser un format supplémentaire”, qui reintroduisent une vulnérabilité discrète.

Construire des tests utiles, pas seulement des tests “qui passent”

Un test utile en audit n’est pas “est-ce que l’image s’affiche”. C’est “est-ce que l’image est servie de manière sûre et cohérente”.

Je recommande de constituer un mini jeu de test:

Des images valides pour chaque format autorisé. Un fichier de test volontairement corrompu, juste pour voir comment le serveur réagit. Si vous autorisez SVG, un SVG minimal et un SVG plus complexe, uniquement en environnement de recette.

L’enjeu n’est pas de lancer une attaque contre votre propre site en production, mais d’observer le comportement: headers, erreurs, fallback, et façon dont WordPress gère les échecs.

J’ai déjà vu des équipes où tout semblait “OK” avec un JPEG valide, mais un format plus rare déclenchait des Content-Type bizarres. Ce décalage venait souvent d’un fichier mal détecté, ou d’une association MIME non couverte dans la config serveur.

Quand la sécurité MIME rencontre la performance et la compatibilité

Il y a un sujet qu’on sous-estime: la compatibilité. Les corrections MIME peuvent avoir des effets collatéraux sur les caches, sur certains comportements de navigateur, ou sur la façon dont un proxy CDN traite le contenu.

Sur un site avec beaucoup d’images, un changement de header ou de règle peut impacter:

le cache si les headers varient, le comportement de certains navigateurs qui interprètent des Content-Type ambigus, l’optimisation si vous avez un système de redimensionnement ou de transformation.

La bonne pratique est d’aller par itération. Par exemple, commencez par corriger ce qui est manifestement incohérent (Content-Type manifestement faux), puis ajoutez ensuite des restrictions plus fines.

Si vous utilisez un CDN ou un reverse proxy devant WordPress, gardez en tête que le proxy peut parfois réécrire ou normaliser les headers, ce qui complique la lecture directe des réponses. Ce n’est pas un blocage, mais c’est une raison supplémentaire d’avoir un test end-to-end.

Résilience: que faire après correction si quelque chose se dégrade

Quand on ajuste la sécurisation WordPress, il faut prévoir une réalité simple: un site n’est pas un laboratoire. Il y a des plugins, des thèmes, des conversions, et parfois des pratiques historiques.

Si après correction vous constatez:

des médias qui ne s’affichent plus, des uploads qui échouent avec une erreur générique, des fichiers qui se téléchargent au lieu de s’afficher,

Alors ne changez pas dix variables à la fois. Revenez au principe de cohérence: qu’est-ce que WordPress autorise, que fait le serveur en réponse, et quel format précis pose problème.

Souvent, l’origine est soit une restriction trop stricte (un format oublié), soit une association MIME partielle (formats couverts et autres non), soit une règle qui ne s’applique pas au bon chemin.

Et si vous avez déjà des fichiers suspects dans les uploads ?

Si vous avez des éléments concrets qui indiquent une tentative d’upload malveillante, la correction des règles MIME ne suffit pas toujours. La question devient alors: que faites-vous du contenu déjà présent?

En audit, je traite ça comme un chantier distinct, avec des étapes claires:

  1. isoler et identifier (quels fichiers, quels chemins, quels dates, quel type annoncé), 2) vérifier les contenus et leur cohérence (headers, comportement navigateur, signatures de base), 3) nettoyer si nécessaire, puis durcir pour empêcher la répétition.

Même si votre serveur “servait” le fichier sans exécuter, le risque reste que des variantes exploitent un autre chemin ou une autre règle, ou que la configuration change plus tard (migration, mise à jour, ajout de module).

Le point d’attention final: garder une cohérence durable

La sécurisation ne s’arrête pas à la correction initiale. WordPress évolue, plugins et thèmes changent les usages, et des mises à jour peuvent modifier les comportements.

Pour éviter de revenir au point de départ, je conseille une discipline simple: garder une référence de ce que vous observez.

Un audit “vivant” peut s’appuyer sur:

un échantillon stable d’URL images pour vérifier Content-Type, un historique de ce que WordPress accepte à l’upload, et une revue régulière des uploads réellement apparus dans wp-content/uploads/.

C’est moins spectaculaire qu’un grand chantier unique, mais c’est exactement ce qui évite les surprises quand un nouveau format est ajouté, ou quand une règle serveur est rechargée par un déploiement.

Si vous le souhaitez, dites-moi votre environnement (Apache ou Nginx, présence d’un CDN, formats utilisés comme WebP ou SVG, et comment vous transférez les médias). Je pourrai vous proposer un plan d’audit plus ciblé, avec les tests à exécuter et les ajustements à envisager pour une sécurisation WordPress cohérente, sans casser la diffusion de vos images.

Edit

Pub: 15 Aug 2026 21:41 UTC

Views: 4