
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.
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.
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é.
On distingue généralement deux grandes familles d’exploitation :
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é :
.php est uploadé sur le serveur, il sera exécuté..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.
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.
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 le nom du fichier contient .jpg sans vérifier la position ou la validité complète, ce fichier peut être interprété comme un script PHP.
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 attendus par l’application.
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.
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.
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 :
config.php, .htaccess)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 :
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.

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 :
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 :
../ (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.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.
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 :

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.
Cependant, si une implémentation personnalisée est nécessaire, voici quelques règles de sécurité fondamentales à respecter :
../, 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.En complément des validations techniques, voici des mesures de défense en profondeur à mettre en place pour renforcer la sécurité :
php.ini :
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