Détection intelligente du type de fichier avec PHP

Dans la plupart des applications Web actuelles, il est nécessaire de permettre aux utilisateurs de télécharger des images, des fichiers audio et vidéo. Parfois, nous devons également limiter le téléchargement de certains types de fichiers, un fichier exécutable étant un exemple évident.

Outre la sécurité, vous pouvez également empêcher les utilisateurs d’utiliser de manière abusive la fonction de téléchargement, par exemple. télécharger illégalement des fichiers de musique protégés par le droit d'auteur et utiliser le service pour promouvoir le piratage! Dans cet article, nous examinerons quelques moyens pour y parvenir.

Détection de type de fichier à l'aide de types d'extension et MIME

Je ne vais pas en parler de manière trop détaillée, car après tout, c’est ce que nous faisons normalement lorsque nous voulons restreindre certains fichiers. Nous obtenons simplement le type MIME du fichier en utilisant $ _FILES ['monFichier'] ['type'] et vérifiez si c'est d'un type valide.

Ou nous pourrions scanner les derniers caractères du nom de fichier et rejeter les fichiers se terminant par une certaine extension. Malheureusement, ces méthodes sont à peine suffisantes, car on peut facilement changer l’extension d’un fichier pour contourner cette restriction. De plus, les informations de type MIME sont fournies par le navigateur et la plupart des navigateurs, sinon tous, déterminent le type mime en fonction de l'extension du fichier! Par conséquent, les types MIME peuvent très facilement être usurpés.

Explorons maintenant quelques autres moyens offrant une meilleure protection contre les imbéciles.

Utiliser des octets magiques

Le meilleur moyen de déterminer le type de fichier consiste à examiner les premiers octets d'un fichier, appelés «octets magiques». Les octets magiques sont essentiellement des signatures dont la longueur varie de 2 à 40 octets dans les en-têtes de fichier ou à la fin d'un fichier. Il existe plusieurs centaines de types de fichiers, et bon nombre d’entre eux sont associés à plusieurs signatures de fichiers. Vous pouvez voir une liste des signatures de fichiers ici.

Bien qu’incohérent, c’est notre meilleur moyen de détecter de manière fiable les types de fichiers. Cette tâche apparemment difficile a été vraiment facilitée par une extension PECL appelée Fileinfo. Depuis PHP 5.3, Fileinfo est fourni avec la distribution principale et est activé par défaut. Il s'agit donc d'un moyen simple et robuste de détecter et d'imposer des restrictions sur les types de fichiers téléchargés.

Voyons maintenant comment détecter un type de fichier à l'aide de Fileinfo:

Gestion des téléchargements d'images

Si vous souhaitez autoriser uniquement le téléchargement d’images, vous pouvez utiliser le logiciel intégré. getimagesize () fonction pour s’assurer que l’utilisateur télécharge réellement un fichier image valide. Cette fonction renvoie false si le fichier n'est pas un fichier image valide.

Lecture et interprétation manuelle des octets magiques

Si, pour une raison quelconque, vous ne pouvez pas installer Fileinfo, vous pouvez toujours déterminer manuellement le type de fichier en lisant les premiers octets d'un fichier et en les comparant aux octets magiques connus associés au type de fichier concerné. Ce processus comporte certainement un élément d’essai et d’erreur, car il existe toujours une chance qu’il existe quelques octets magiques non documentés associés à des formats de fichiers légitimes. En conséquence, des fichiers valides pourraient être rejetés par votre système. Cependant, ce n’était pas impossible il ya quelques années. On m’a demandé de travailler sur un script qui ne permettait d’importer que des fichiers mp3 authentiques. Comme nous ne pouvions pas utiliser Fileinfo, nous avons eu recours à ce balayage manuel. Il m'a fallu un certain temps pour rendre compte de certains octets magiques non documentés pour le format mp3, mais très vite, un script de téléchargement stable a été exécuté.

Avant de terminer, je voudrais juste me séparer d’un mot d’avertissement général: veillez à ne jamais appeler un correspondant. comprendre() avec un fichier qui a été téléchargé, le code PHP peut très bien être caché dans l’image, et l’image passerait très bien vos tests de validation de fichier, dans le seul but de causer des dégâts lorsqu’elle sera exécutée par le serveur.