Upload de fichier - toute une histoire

Introduction

Lors de la mise en place d'une fonctionnalité d'upload, il faut se poser la question de comment sécuriser la porte que nous ouvrons sur le systéme d'information. Il est facile de faire en sorte que les utilisateurs puissent envoyer des fichiers. Le probléme étant que des personnes mal intentionnées peuvent utiliser ce canal pour effectuer des opérations qui ne sont pas du tout en adéquation avec les utilisateurs valides. 

L'autre aspect qu'il ne faut pas oublier c'est l'optimisation. Il est vrai qu'avec l'accroissement des capacités des serveurs, on ne se pose pas trop la question... Toutefois, si vous êtes de ceux qui souhaite montrer que vous êtes économe quant à l'usage des ressources alors vous trouverez ce qu'il vous faut dans le paragraphe sur les choix de mises en place d'un mécanisme d'upload.

Sécurité

Lorsqu'un hacker a compromis le compte d'une personne lambda sur la plateforme (via ce qu'on appelle une technique de "social engineering"). Il peut alors tenter de pénétrer encore plus loin sur le systéme par ce canal si on ne prends pas de précaution.

Les principales tentatives vont-être:

  1. Via des attaques DS ou Denial of service
  2. Uploader des virus ou des malware
  3. Compromettre le réseau ou les serveurs par d'autres méthodes

Il ne faut pas oublier que l'upload de code malicieux est trés fréquent d'autant que c'est la premiére étape pour éxecuter le code que l'on souhaite :

  • Récupérer le controle du systême.
  • Surcharger le système pour le faire disfonctionner
  • Compromettre l'utilisateur ou les données du système
  • Afficher des "graffitis" sur l'affichage publique de la plateforme

De ce fait, les principales étapes à suivre pour réduire les réussites provenant de ces attaques sont :

  • Les fichiers uploadés doivent être déposé dans une zone dédieé, dans l'idéal n'étant pas sur le volume associé à l'OS.
    • Le fait de définir une zone dédiée rends plus simple l'imposition des restrictions sécuritaires
      • Ex: Désactiver les permissions d'éxecution des fichiers dans la zone d'upload.
  • Ne pas faire persister les fichiers ainsi fournit par les utilisateurs dans la même arborescence que l'application
  • Utiliser un nommage des fichiers suffisament sécurisé qui est déterminé par l'application et pas par les utilisateurs.
    • notamment faire un html encode du nom du fichier pour ne pas faire confiance au nommage afficher par la suite, ou tracer et provoquer à l'usage des effets de bord.
    • Pour information Razor encode automatiquement en html le rendu
  • Autoriser uniquement les extensions pertinentes pour l'application
  • S'assurer que les vérifications effectuées côté client soit également effectuer du côté serveur.
  • Vérifier la taille des fichiers uploade. Permet de limiter l'utilisation abusive de la bande passante du serveur
  • S'assurer que les fichiers ne s'écrase pas les uns les autres quelques soit la solution de stockage (Disque ou db)
  • Mettre en place un systéme de scanner de malware / virus sur les fichiers avant même qu'ils soient déposé sur le disque du serveur.

De ce fait, il est important de réduire la surface d'attaque lorsque le système doit accepter des fichiers des utilisateurs. Ainsi, je vous conseille de lire les pages suivantes :

Implémentation de l'upload de fichier

C'est un vaste sujet qui dans le contexte de l'upload des fichiers peut-être vu sous deux aspects :

  • Le stockage des fichiers
  • Le processus d'upload à proprement dit.

Le stockage des fichiers

Avec les derniéres technologies actuelles, nous avons trois méthodes de stockages qui reviennent dans la plus part des scénarios. :

  • La base de données
    • Lorsque les fichiers ne sont pas trés volumineux, c'est souvent le moyen le plus rapide que l'utilisation d'un système de fichier physique.
    • Une base de données est souvent plus adaptée car il est possible de retrouver des métadonnées associées au fichier avec un même contexte. Cela rend les accès aux informations beaucoup plus simple.
    • Une base de données toutefois est plus complexe à mettre à l'échelle que du matériel de stockage plus classique.
  • Un stockage physique ( Systéme de fichier ou partage réseau)
    • C'est utile pour des gros fichier
      • Les bases de données ont souvent des restrictions sur la taille d'un upload
      • L'espace de stockage est souvent plus économique qu'une base de donnée.
    • Le stockage physique est en général bien moins couteux qu'un service de stockage dédié.
    • Les processus applicatifs doivent pouvoir lire et écrire sur l'emplace de stockage : et ne jamais avoir la possibilité d'exécution
  • Un service de stockage (Azure storage, OneDrive, etc)
    • C'est un service qui offre une possibilité de mise à l'échelle et une fiabilité trés importante vis à vis de solution sur site classique qui sont plus sujet aux erreurs.
    • Les services ont un cout relativement bas pour des infrastructure dont le stockage est important en terne de volumétrie.

La gestion du mécanisme d'upload

Il y a deux grandes approches pour gérer les uploads :

  • Le buffering
  • Le streaming

Buffering

Le fichier entier est lut depuis l'objet IFormFile en c#, c'est une représentation de l'utilisation du fichier en cours de traiement ou du fichier à sauvegarder. Les ressources (Stockage disque, mémoire) utilisé par le fichier dépendra de la quantité et la taille des autres fichiers en cours d'upload au même moment. Si une application tente d'utiliser trop de buffer car il y a trop d'upload simultanée alors l'application cessera de fonctionner lorsqu'elle manquera de mémoire ou d'espace de stockage. Ainsi si la taille ou la fréquence d'utilisation des uploads de fichier dépasse les ressources applicatives, il est préférable d'utiliser un mécanisme de streaming.

Remarque : Un simple buffer de fichier qui dépasse 64K est déplacé de la mémoire au fichier temporaire sur le disque.

Streaming

Le fichier dans ce scénario provient d'une requête "multipart" et est directement traité ou sauvegardé par l'application. Le streaming n'améliore pas significativement les performances. Toutefois, cela permet de réduire le coût en mémoire et espace disque au moment de l'upload. Ainsi, il est possible de gérer potentiellement plus de requêtes en simultannées.

 


Rejoindre la conversation