Sur de nombreuses applications web, la possibilité d’uploader des fichiers fait partie des fonctionnalités standard.
Qu’il s’agisse d’ajouter une photo de profil ou de transmettre un document, l’upload de fichiers simplifie les interactions utilisateurs. Mais cette fonctionnalité n’est pas sans risques.
Mal configurée ou insuffisamment protégée, cette fonctionnalité peut ouvrir la porte à des attaques graves, allant de l’exécution de code malveillant sur le serveur à la compromission complète de l’infrastructure. Un simple fichier en apparence anodin peut devenir un cheval de Troie, permettant à un attaquant de prendre le contrôle du système ou d’en perturber le fonctionnement.
Dans cet article, nous passerons en revue les vulnérabilités liées à l’upload de fichiers. Nous détaillerons les différentes techniques utilisées par les attaquants pour contourner les mécanismes de sécurité. Enfin, nous présenterons les bonnes pratiques à mettre en place pour sécuriser efficacement une fonctionnalité d’upload.
Guide complet sur les failles d’upload de fichiers
- Vulnérabilités d’upload de fichiers : mécanismes d’exploitation et risques
- Comprendre les techniques pour contourner les protections et exploiter des vulnérabilités d'upload de fichiers
- Exemples d'exploitations de failles d'upload de fichiers
- Comment prévenir les vulnérabilités d'upload de fichiers ?
- Conclusion
Vulnérabilités d’upload de fichiers : mécanismes d’exploitation et risques
L’upload de fichiers représente une surface d’attaque critique lorsqu’il est mal sécurisé. De nombreuses méthodes permettent d’en exploiter les failles, avec pour objectif principal d’uploader un fichier dont le type ou le contenu n’est pas prévu, voire mal interprété par l’application.
Certaines attaques peuvent même s’appuyer sur des fichiers apparemment légitimes, autorisés par le système, mais utilisés de manière détournée pour compromettre la sécurité.
Modes d’exploitation d’un upload de fichiers
On distingue généralement deux grandes familles d’exploitation :
- Côté client : un attaquant peut injecter du code JavaScript malveillant dans un fichier, ce qui permet par exemple de déclencher une faille XSS stockée lors de son affichage par un utilisateur.
- Côté serveur : l’upload peut être utilisé pour exécuter du code arbitraire, contourner des restrictions ou atteindre une exécution de commandes système, selon la configuration du serveur.
Fonctionnement d’un upload de fichiers côté serveur
Lorsqu’un serveur web reçoit une requête pour un fichier avec l’extension .php
par exemple, il ne se contente pas de servir ce fichier tel quel. À la place, il le transfère à un moteur d’exécution PHP, comme mod_php
pour Apache ou PHP-FPM
pour Nginx.
Ce moteur va alors interpréter le contenu du fichier, exécuter les instructions qu’il contient (y compris d’éventuelles commandes système), et générer une sortie, généralement en HTML.
Le serveur web renvoie ensuite le résultat de cette exécution au client, sous forme de réponse HTTP. Le code PHP lui-même n’est jamais transmis tel quel au navigateur de l’utilisateur. Ce mécanisme permet à la fois d’afficher du contenu dynamique et de protéger le code source côté serveur.
Ce fonctionnement a des implications majeures en matière de sécurité :
- Si un fichier malveillant avec une extension
.php
est uploadé sur le serveur, il sera exécuté. - En revanche, si un fichier
.php
est placé dans un répertoire non interprété par PHP (ou renommé avec une autre extension), il peut être téléchargé comme un simple fichier texte, exposant ainsi le code source.
Une mauvaise configuration peut donc exposer le code ou permettre l’exécution de commandes à distance, en particulier si un webshell est uploadé dans un dossier mal protégé.
Dans les sections suivantes, nous allons détailler ces différentes vulnérabilités et illustrer leurs impacts via des exemples concrets. Enfin, nous présenterons les bonnes pratiques de sécurité à mettre en place pour se prémunir efficacement contre ces attaques.
Mais avant cela, passons en revue les mécanismes de sécurité les plus courants, ainsi que les techniques utilisées par les attaquants pour les contourner.
Comprendre les techniques pour contourner les protections et exploiter des vulnérabilités d’upload de fichiers
Contournement des contrôles d’extension de fichiers
La vérification de l’extension d’un fichier côté serveur est une première ligne de défense indispensable. Cependant, elle ne garantit pas à elle seule la sécurité du mécanisme d’upload.
En effet, les attaquants disposent de nombreuses techniques pour contourner ces validations lorsque celles-ci sont mal implémentées.
Extensions multiples
Une méthode classique de contournement consiste à utiliser des extensions doubles ou déguisées, comme image.jpg.php
.
Si l’application se contente de vérifier que l’extension contient .jpg
sans vérifier la position ou la validité complète, ce fichier peut être interprété comme un script PHP.
Les limites des blacklists
De nombreuses applications s’appuient sur une blacklist d’extensions interdites, bloquant par exemple les .php
. Cependant, cette approche est facilement contournable avec des variantes comme .php5
, .phtml
, ou d’autres extensions interprétables selon la configuration du serveur.
De fait, il est vivement recommandé de privilégier une whitelist d’extensions autorisées (comme .jpg
, .png
, .pdf
) pour ne laisser passer que les types de fichiers explicitement sûrs.
Fuzzing et techniques en boite noire
Dans un contexte black box, un attaquant va souvent pratiquer du fuzzing d’extensions pour identifier les formats acceptés ou mal filtrés par l’application.
Cette phase de test permet de découvrir des comportements inattendus ; et des extensions potentiellement dangereuses.
Injection de caractères spéciaux
L’utilisation de caractères spéciaux dans les noms de fichiers est une autre technique pour tromper la validation :
%20
%0a
%00
%0d%0a
/
ou.\
Ces caractères peuvent perturber les filtres et provoquer une mauvaise interprétation du nom ou du chemin du fichier côté serveur.
Risques de Path Traversal
Un danger important lié aux noms de fichiers mal filtrés est l’injection de chemins relatifs (../
), ou Path Traversal. Elle permet à un attaquant de remonter l’arborescence du système de fichiers et :
- Surcharger ou modifier des fichiers sensibles (ex :
config.php
,.htaccess
) - Placer des fichiers malveillants à des emplacements stratégiques accessibles via HTTP
Contournement du type MIME des fichiers
Le type MIME (Multipurpose Internet Mail Extensions), défini par la RFC 6838, est utilisé pour indiquer le format d’un fichier.
Il est composé de deux parties : le type principal et le sous-type, par exemple image/gif
. Lorsqu’un fichier est uploadé, cette information est transmise via l’en-tête Content-Type
.
Côté serveur, cette validation peut être effectuée de deux manières :
- Vérification du Content-Type : basée sur la valeur envoyée dans la requête HTTP.
- Analyse des signatures de fichiers (aussi appelées magic bytes) : ce sont des séquences d’octets situées au début du fichier, typiques de chaque format (ex. :
GIF89a
pour les GIF).
Malheureusement, s’appuyer uniquement sur ces deux vérifications ne suffit pas à garantir la légitimité du fichier. En effet, un attaquant peut fabriquer un fichier hybride, combinant une signature valide (par exemple, celle d’un fichier image), un Content-Type crédible (image/gif
) et un code malveillant dissimulé, comme un webshell PHP.
Upload de fichiers avec la méthode PUT
La méthode PUT définie par la RFC 7231 stipule :
« La méthode PUT demande que l’état de la ressource cible soit créé ou remplacé par l’état défini par la représentation incluse dans la charge utile du message de demande. »
En clair, lorsqu’un serveur autorise l’utilisation de la méthode HTTP PUT, il accepte qu’un fichier soit créé ou remplacé à l’emplacement spécifié par l’URL, avec le contenu défini dans le corps de la requête. Cela ouvre la voie à de graves failles de sécurité, si cette fonctionnalité n’est pas correctement restreinte.
Heureusement, cette méthode n’est pas activée par défaut sur la majorité des serveurs web. Elle nécessite une configuration explicite pour devenir opérationnelle. Toutefois, lors de tests d’intrusion, il arrive fréquemment de découvrir des serveurs mal configurés, où la méthode PUT est active sans contrôle d’accès.
Dans ce cas de figure, une telle configuration permettrait à un attaquant de :
- Uploader un webshell à savoir un fichier contenant du code malveillant (généralement PHP) pouvant être exécuté côté serveur.
- Modifier ou remplacer des fichiers critiques ; impactant potentiellement la configuration ou le fonctionnement global de l’application.
- Déclencher un déni de service (DoS) en écrasant des fichiers essentiels au bon fonctionnement de l’application.
Conséquences potentielles d’une faille d’upload de fichiers
Une mauvaise gestion de l’upload de fichiers peut avoir des conséquences critiques sur la sécurité d’une application web. Lorsqu’un attaquant parvient à exploiter une vulnérabilité dans ce mécanisme, plusieurs types d’attaques deviennent possibles :
- Failles XSS (Cross-Site Scripting) : Les fichiers SVG, souvent considérés comme sûrs car de type image, peuvent contenir du JavaScript malveillant. Si ces fichiers sont consultés via un navigateur, ils peuvent déclencher une attaque XSS stockée, exécutant du code arbitraire dans le contexte de la session de l’utilisateur cible.
- Upload de fichier arbitraire : Sans contrôle rigoureux du nom de fichier, un attaquant peut injecter des caractères spéciaux comme
../
(path traversal) afin de sortir du répertoire prévu et surcharger ou écraser des fichiers sensibles sur le serveur (ex. :.htaccess
, fichiers de configuration, etc.), selon les permissions du système. - Attaque par déni de service (DoS) : Si aucune limite de taille n’est imposée lors de l’upload, il devient possible d’inonder le serveur avec des fichiers volumineux, entraînant une saturation des ressources, voire un crash pur et simple de l’application.
- Exécution de commandes à distance (RCE) : Le scénario le plus dangereux : l’upload d’un webshell. Il s’agit d’un fichier contenant du code interprété côté serveur (PHP, ASPX, etc.), permettant à l’attaquant de prendre le contrôle du système distant, d’exécuter des commandes, et potentiellement de pivoter vers d’autres cibles. Pour en savoir plus sur ce type de vulnérabilité, vous pouvez consulter notre write-up : Une vulnérabilité RCE dans un nom de fichier.
Exemples d’exploitations de failles d’upload de fichiers
Attaque XSS via upload de fichier SVG
Les attaques XSS (Cross-Site Scripting) liées aux uploads de fichiers sont une vulnérabilité fréquemment rencontrée lors de tests d’intrusion web. L’un des vecteurs les plus courants et efficaces repose sur l’utilisation de fichiers SVG.
Les fichiers SVG sont un format d’image basé sur XML. Il est donc possible d’inclure des balises JavaScript dans leur structure.
Ces balises peuvent être exécutées par le navigateur de la victime lorsqu’elles sont ouvertes, ce qui peut permettre l’exécution de code malveillant :
Imaginons une application web qui permet d’uploader des fichiers avec l’extension .svg
:
Le fichier SVG est bien uploadé sur le serveur. Cependant, lorsqu’un utilisateur y accède via son navigateur, le contenu malveillant intégré dans le fichier est interprété et exécuté. Cela déclenche l’exécution du code JavaScript, permettant par exemple de récupérer le cookie de session de l’utilisateur ciblé :
Par ailleurs, un attaquant peut uploader une image SVG piégée, puis partager le lien vers ce fichier avec des utilisateurs légitimes. Dès qu’un utilisateur clique sur ce lien, le code JavaScript contenu dans le fichier est exécuté dans son navigateur. Cela peut permettre à l’attaquant de voler des informations sensibles, comme un jeton de session, ou de provoquer tout autre effet typique d’une XSS stockée.
Dans certains cas, le fichier malveillant peut même être affiché automatiquement sur une page publique (par exemple, la page d’accueil d’un site ou un espace communautaire). Les utilisateurs seront alors exposés à l’attaque sans avoir besoin de cliquer sur quoi que ce soit, simplement en visitant la page.
Exécution de code à distance via upload d’un webshell
Prenons l’exemple d’un upload de webshell sur une application vulnérable. Cette attaque repose sur l’upload d’un fichier contenant du code malveillant, avec une extension interprétée par le moteur PHP. Si ce fichier est exécuté côté serveur, l’attaquant peut alors exécuter des commandes à distance, ouvrant la voie à une prise de contrôle partielle ou totale du système.
Voici le code vulnérable :
Dans cet exemple, l’upload d’un fichier est autorisé à condition que sa signature corresponde à celle d’un fichier JPEG ou PNG. Par exemple, pour un fichier JPEG, les premiers octets doivent correspondre à la signature hexadécimale FFD8
.
Il est d’ailleurs facile de retrouver les signatures (« magic bytes ») propres à chaque type de fichier :
Grâce à ce contournement, le fichier est correctement uploadé sur le serveur. En accédant à son emplacement, il devient possible d’exécuter des commandes à distance :
Comment prévenir les vulnérabilités d’upload de fichiers ?
Il est fortement recommandé de s’appuyer sur des frameworks éprouvés pour gérer les mécanismes d’upload et de validation de fichiers. Cela réduit significativement les risques d’erreurs et de vulnérabilités.
Valider le contenu des fichiers
Cependant, si une implémentation personnalisée est nécessaire, voici quelques règles de sécurité fondamentales à respecter :
- Validation de l’extension : restreignez les types de fichiers acceptés (par exemple, aux formats d’image uniquement) en mettant en place une liste blanche d’extensions autorisées.
- Vérification du type MIME et de la signature (magic bytes) : Ne vous fiez pas uniquement à l’extension ; validez également le Content-Type et les bytes caractéristiques (signature binaire) du fichier pour confirmer qu’il s’agit bien du type attendu.
- Contrôle strict du nom de fichier : Évitez les noms contenant des caractères spéciaux ou des séquences dangereuses comme
../
, qui pourraient entraîner des vulnérabilités de type path traversal. Privilégiez une liste de caractères autorisés (ex. alphanumériques) pour les noms de fichiers.
Mesures de sécurité supplémentaires
En complément des validations techniques, voici des mesures de défense en profondeur à mettre en place pour renforcer la sécurité :
- Masquer le répertoire de stockage : Évitez de rendre public le chemin où sont stockés les fichiers uploadés. Préférez un script serveur dédié pour servir les fichiers au client, ce qui permet un contrôle précis des accès et évite l’exécution directe d’un fichier malveillant.
- Renommer les fichiers avec des noms aléatoires : Lors de l’enregistrement, attribuez un nom unique et imprévisible (UUID, hash…) à chaque fichier afin d’empêcher les attaques par brute force d’URL ou la réutilisation de fichiers malveillants.
- Limiter les fonctions critiques du langage serveur : Désactivez les fonctions sensibles dans la configuration de votre langage backend. Par exemple, en PHP, vous pouvez désactiver les fonctions à risque via le fichier
php.ini
:
- Limiter la taille des fichiers uploadés : Définissez une taille maximale stricte pour les fichiers à uploader afin de prévenir les tentatives d’attaques par déni de service (DoS), qui peuvent consister à saturer les ressources du serveur avec des fichiers trop volumineux.
- Déployer un WAF (Web Application Firewall) : Un WAF permet de détecter et bloquer les requêtes malveillantes avant qu’elles n’atteignent l’application. Il constitue une couche de défense supplémentaire utile contre les attaques courantes. Néanmoins, un WAF ne doit jamais être considéré comme une protection unique. Certains attaquants expérimentés peuvent le contourner. Il est donc essentiel de l’intégrer dans une stratégie de sécurité plus globale.
Conclusion
L’upload de fichiers représente une faille critique potentielle pour les applications web lorsqu’il est mal implémenté.
Des attaques telles que le XSS, l’exécution de commandes à distance ou encore l’upload de fichiers arbitraires peuvent avoir des impacts majeurs sur la sécurité et la réputation d’une entreprise.
Pour réduire significativement ces risques, il est essentiel de respecter des bonnes pratiques de sécurité et de s’appuyer sur des frameworks éprouvés. Une implémentation rigoureuse du mécanisme d’upload constitue une première ligne de défense efficace pour protéger les applications.
Auteur : Théo ARCHIMBAUD – Pentester @Vaadata