Principes de base pour la sécurisation et l'optimisation des fichiers et des scripts

Exemple de configuration pour contrôler les extensions et la taille maximale des fichiers. L'input de type file est également renseigné avec l'attribut "accept" dans le html. Côté pratique, ces variables sont transmises par php dans le html et la classe javascript les récupère dans le html, ce qui permet de grouper ces paramètres dans le code php, tout en permettant au script javascript de pouvoir être externalisé.
Extensions autorisées : jpg, jpeg, png, mpg, mpeg, mp4, mts, m2ts, docx, odt, pdf, Taille max : 500 Mo


L'attribut "accept" est facilement contournable et la restriction des extensions en javascript permet simplement d'avoir un retour d'information dès la sélection du fichier en cas d'erreur. En aucun cas les configurations ou contrôles côté client peuvent être considérés comme des mesures de sécurité.

Les contrôles de sécurité se font impérativement côté serveur.

Ces contrôles sont indispensables si votre formulaire est destiné à un espace public non protégé. Ils peuvent être relativisés s'il est destiné à une page administrateur protégée, mais ils sont conseillés autant que possible.

1/ Contrôle et sécurisation des fichiers

Le fichier serveur UploadAjaxABCI_Upload_Basique_Controle.php situé dans dossier "Php_Upload" est utilisé pour le formulaire ci-dessus et montre la configuration minimale pour le contrôle des fichiers. A privilégier pour sa simplicité pour les besoins basiques.

Le fichier UploadAjaxABCI_Upload_Basique_Controle_Multiple.php utilisé pour le second formulaire en bas de page, montre d'autres possibilités si votre formulaire comporte plusieurs champs de type file, ainsi que l'optimisation des fichiers images.


- Contrôle des extensions autorisées
C'est le contrôle minimum requis comme mesure de sécurité côté serveur. Grand danger si ce contrôle n'est pas fait.
Les systèmes d'exploitation n'ouvrent pas les fichiers qui ne correspondent pas à leur extension, une attaque directe est donc difficilement réalisable si vous avez contrôlé l'extension. Cependant, on pourrait trouver un moyen détourné (si par ailleurs le système est infecté par un virus par exemple) qui pourrait éventuellement exploiter ces fichiers, d'où l'importance de contrôler également le type MIME pour éviter de laisser sur le disque dur des fichiers potentiellement dangereux.

- Contrôle du type MIME
La classe d'upload serveur vérifie que le type MIME du fichier correspond à son extension. C'est le seul contrôle effectué par défaut par la classe Php d'upload depuis la version 7.5. Cela permet d'éviter de charger des fichiers indésirables en changeant simplement leur extension. Seule exception pour les fichiers ayant des extensions différentes qui désignent un même type de fichier, par exemple "jpg" ou "jpeg", on pourrait donc renommer une extension "jpg" en "jpeg" sans que le contrôle émette une erreur, mais peu importe puisque les fichiers sont identiques.
Notez que suivant les serveurs (suivant la base magique utilisée), certains fichiers ne seront pas reconnus, notamment ceux de type MTS et m2ts. Si vous désactivez ce contrôle pour certaines extensions, comme montré en exemple dans les scripts serveur de ces deux exemples de formulaire, ayez conscience que l'on pourra charger n'importe quel type de fichier en le renommant avec ces extensions.

- Contrôle de la taille des fichiers
Cette mesure est utile pour éviter que des utilisateurs mal intentionnés téléchargent de très gros fichiers qui saturent votre espace disponible ou vos ressources serveur. Le téléchargement de très gros fichiers ne devrait être rendu possible que dans un espace authentifié, et si besoin contrôlé par des données non volatiles comme par exemple l'enregistrement du cumul des téléchargements dans une base de donnée.

- Contrôles complémentaires
Ouvrir le fichier avec Php et lui appliquer éventuellement des fonctions de traitement Php. Ce traitement renforce la sécurité puisque Php renverra la plupart du temps une erreur si le fichier est corrompu. Prendre cependant en considération la mémoire requise pour ce type de contrôle, ce qui est limitant si vous souhaitez qu'un maximum de visiteurs puissent télécharger des fichiers en même temps. De même, le traitement (réorientation, optimisation, redimensionnement, recadrage, création de filigrane) des grosses images, requière beaucoup de mémoire (+ de 100Mo), ce qui limitera leur taille admissible suivant la configuration de votre serveur.
Le code serveur du second formulaire montre un exemple pour optimiser les images pour le Web (réduit leur poids tout en préservant une qualité suffisante pour l'affichage), et une option pour mesurer la mémoire requise (vers la fin de script). La gestion des erreurs fatales est gérée par la classe d'upload qui renverra un message adéquat en cas de dépassement de la directive "memory_limit" de votre serveur, sans interrompre le téléchargement des fichiers suivants en cas d'upload multiple.
2/ Sécurisation des scripts

- Token de sécurité
Tous les scripts côté serveur utilisent un token, enregistré dans une variable de session, qui permet de s'assurer que le fichier a été transmis en passant par le formulaire. Le piratage des sessions est possible avec un accès http dans certaines conditions, par exemple un pirate pourrait écouter le réseau derrière un proxy (accès internet dans les lieux publics). Evitez si possible les hébergements qui ne proposent pas le protocole https ("s" pour secure car les données sont chiffrées).

- Variables en provenance du formulaire
Par définition, on ne peut pas faire confiance aux données provenant du client. Cela vaut pour tout type de données.
Par exemple, si le dossier de destination est uniquement dépendant du nom du champ de type file, rien n'empêche de modifier le nom de ces champs dans la console du navigateur et donc de modifier cette destination. Il est donc essentiel de contrôler les dossiers de destination côté serveur.

Les images seront téléchargées dans le dossier "Destination_Upload1", les vidéos dans le dossier "Destination_Upload2" et les documents dans le dossier "Destination_Upload3". Les images sont optimisées pour le Web.

Images jpg, jpeg, png, max 20 Mo. Vidéos mpg, mpeg, mp4, mts, m2ts, max 750 Mo. Documents docx, odt, pdf, max 50 Mo     


Par ailleurs, vous devriez toujours nettoyer le nom des fichiers si vous souhaitez utiliser le nom du fichier fourni par l'utilisateur. La méthode serveur getcleanFileName() permet de retourner le nom du fichier nettoyé. Cela vous assure que ce fichier sera toujours accessible, en même temps qu'il vous protège contre des caractères qui pourraient permettre de naviguer dans l'arborescence des répertoires.


3/ Optimisation des scripts pour l'upload des photos

Si votre formulaire permet l'upload d'images, il est recommandé d'utiliser la classe CorrectionExifJpg() (utilisée dans le code serveur du premier formulaire) qui corrige l'orientation de certaines images "jpg/jpeg" en fonction de ses informations EXIF pour compatibilité avec certains APN, excepté si vous utilisez la classe ImgGD() qui possède sa propre méthode de correction d'orientation. Si vous utilisez conjointement ces deux classes, une double correction produira une mauvaise orientation des images (pour celles qui ont besoin d'être réorientées).
A noter que cette classe n'est utile que lorsque vous ne souhaitez pas optimiser vos images pour le web, pour des besoins d'impression grand format de très haute qualité par exemple. La classe ImgGD(), appliquée dans le code serveur du second formulaire, crée des images optimisées pour le web, sans perte de qualité visuelle apparente, en fournissant des fichiers beaucoup plus légers qui accélèrent grandement la vitesse d'affichage suivant les recommandations du Web.

La méthode "catchErrorServer" utilisée en complément, permet de créer des messages d'erreur personnalisés en cas de dépassement de la configuration "memory_limit" du serveur lors du traitement des images. Voir le code serveur de ce formulaire, ainsi que les fichiers de traitement d'images (redimensionnement, crop, filigrane) pour d'autres exemples d'utilisation.


4/ Maintenance, nettoyage du dossier d'upload temporaire

Vous pouvez utiliser la classe NettoyageTemp pour supprimer les fichiers du dossier d'upload temporaire qui sont devenus obsolètes. Cette classe de maintenance n'est pas nécessaire pour le processus d'upload lui-même, mais cela permet de ne pas encombrer votre serveur avec d'éventuels fichiers devenus inutiles. Plus d'information ici.

Depuis la version 7.6b de ce module d'upload, tous les fichiers d'exemples de formulaires utilisent la fonction NettoyageTemp::interval() configurée par défaut. Les valeurs utilisées par défaut sont récupérées dans le fichier "ParamsDefautServeur". Si donc, pour des besoins particuliers, vous définissez des valeurs différentes pour le dossier temporaire et la durée de vie du cookie de sauvegarde, en les passant en paramètre dans l'initialisation de la classe d'upload "UploadAjaxABCIServeur", il faudra renseigner la fonction de nettoyage utilisée avec les valeurs correspondantes.

Index