La faille upload

Auteur : palkeo
Créé le : le 06/09/2008 à 18:28
Visualisations : 3505
Ce tutoriel est composé des parties suivantes :

Introduction

L'upload de fichiers en PHP est utilisé par de nombreux sites, mais peut s'avérer dangereux pour la sécurité.
Dans ce tutoriel, nous verrons comment créer un script d'upload sécurisé.

Premier danger : L'extension du fichier

Tout d'abord, il existe un problème simple, mais trop souvent négligé : L'extension du fichier !
Par exemple, sur un site d'envoi d'images : Seules quelques extensions d'images doivent êtres acceptées, et l'extension du fichier uploadé doit être systématiquement vérifiée.
Imaginez qu'un utilisateur mal intentionné uploade un fichier s'appelant "test.php", et contenant du code PHP : si le scripte uploade le fichier et le rend accessible, il pourra avoir un accès complet aux bases de données du site, et pourra se servir de votre serveur comme proxy, plateforme d'envoi de spam, client Peer-to-peer... Voire pire.

Pour vérifier l'extension du fichier, il suffit d'utiliser la fonction strrchr(), qui trouve la dernière occurrence d'un caractère dans une chaîne, puis retourne la fin de cette chaîne.
Par exemple :
Code : PHP
echo strrchr('test.php', '.');
Affichera ".php"
Pour retirer le ".", il suffit de faire :
Code : PHP
echo substr(strrchr('test.php', '.'), 1);
Donc, pour vérifier que l'extension fait partie d'un panel d'extensions correcte, il va falloir faire :
Code : PHP
$extensionsAutorisees = array('png', 'gif', 'jpg', 'txt', 'pdf'); // Liste des extensions autorisées, en minuscule
$extension = strtolower(substr(strrchr($_FILES['monFichier']['name'], '.'), 1)); // On récupère l'extension du fichier
if(! in_array($extension, $extensionsAutorisees))
 die('Extension incorrecte !');
Ce code va vérifier que le fichier uploadé nommé "monFichier" a bien une extension correcte, et, si ce n'est pas le cas, il va arréter le script en affichant "Extension incorrecte !".

Second danger : le type MIME

Le type MIME, c'est quoi ?
Le type MIME, c'est le renseignement donné par $_FILES['monFichier']['type']
Par exemple, pour un fichier .png, ce sera : image/png

Si, dans votre script d'upload, vous ne vérifiez pas l'extension, mais a la place, le type MIME, sachez que votre script est vulnérable !
En effet, le type MIME est falsifiable !
Il est défini par l'utilisateur, ce qui veut dire qu'il est possible d'uploader un fichier PHP, en lui donnant pour type : "image/png" par exemple !
Le pire, c'est que c'est très simple : par exemple, avec firefox, et l'extension "Tamper Data", en trois clic de souris, on peut modifier le type MIME d'un fichier avant de l'uploader.

Actuellement, il existe encore trop de script vérifiant seulement le type MIME.

Extrait de code présentant une faille :
Code : PHP
...
$type_file = $_FILES['fichier']['type'];
if( !strstr($type_file, 'jpg') && !strstr($type_file, 'bmp') && !strstr($type_file, 'gif') )
{
 exit("Le fichier n'est pas une image");
}
...

Conclusion

Nous avons donc vu les deux principaux problèmes de sécurité posés par l'upload.

Si vous souhaitez faire un script d'upload de fichier, je vous recommande ce tutoriel.