web-dev-qa-db-fra.com

PHP Valider le téléchargement du fichier

Je suis un PHP débutant et j'apprends actuellement la partie "Validation du téléchargement de fichier".

J'ai créé une page test.php contenant le code suivant: 

var_dump(@$_FILES['file']['type']);

Tout d'abord, j'ai téléchargé une image "img.gif" et elle a renvoyé:

string 'image/gif' (length=9)

Ensuite, j'ai changé l'extension de l'image en ".jpg" et elle a renvoyé:

string 'image/jpeg' (length=10)

J'ai donc réalisé que $ _FILES ["fichier"] ["type"] ne renvoyait que l'extension de fichier téléchargée, mais ne vérifiait pas réellement de quel fichier il s'agissait. 

Dans cette page, http://www.w3schools.com/php/php_file_upload.asp , il y a un code:

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

Je me demande pourquoi les codes ci-dessus vérifient l'extension de fichier deux fois? J'ai supprimé certains codes ci-dessus et voici mon nouveau code:

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if (($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts))

Mon code est-il correct? Ou avez-vous de meilleurs moyens de valider que le fichier de téléchargement est une image?

Merci!

8
nut

Vous devez passer le nom_mpType du fichier * à getimagesize , il vous indiquera la taille et le type de l’image (s’il s’agit d’une image). Si l'argument passé est un fichier mais pas une image, il retourne false, cela vous permettra de valider.

Edit: La seule méthode fiable de validation des images consiste à en faire une copie à l’aide de Gd ou Imagick - getimagesize peut être facilement piraté .

*: Je veux dire, le fichier temporel créé après le téléchargement.

Par exemple:

if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
    $file = $_FILES['file']['tmp_name'];
    if (file_exists($file))
    {
        $imagesizedata = getimagesize($file);
        if ($imagesizedata === FALSE)
        {
            //not image
        }
        else
        {
            //image
            //use $imagesizedata to get extra info
        }
    }
    else
    {
        //not file
    }
}

Ce code utilise file_exists juste pour être général. Dans le cas où aucun fichier n'aurait été téléchargé, vous obtiendrez $_FILES['file']['size'] = 0, $_FILES['file']['tmp_name'] = '' et $_FILES['file']['error'] = 4. Voir aussi is_readable . Pour les valeurs d'erreur, voir les erreurs de téléchargement de fichier expliquées à php.net .

15
Theraot
$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

Ceci est vérifié deux fois parce que l'extension du fichier et le 'type de fichier' peuvent être différents, de sorte que quelqu'un ne peut pas télécharger le fichier exécutable avec l'extension .png.

Dans votre code modifié, il est possible de télécharger un type de fichier différent avec une extension modifiée. comme s'ils pouvaient télécharger un document Word avec l'extension ".png".

Votre nouveau code ne fait que vérifier l'extension et ne double-contrôlez pas.

3
Maulik Vora

Votre nouveau code ne vérifie que l'extension du fichier et sa taille. Il ne vérifie pas le type du fichier.

Je vous recommande fortement d'utiliser votre ancien code car il vérifie également le type de fichier.

0
Yogesh Suthar