Script de téléchargement sécurisé

Aug 17 2020

Je crée un réseau social qui permet aux utilisateurs de télécharger une photo de profil. Je veux juste savoir si c'est une manière sûre de le faire. Merci.

<?php

include 'includes/header.php';
include 'includes/form_handlers/settings_handler.php';

//$userPic = ''; $date_time = date('Y-m-d_H-i-s');

if(!empty($userLoggedIn)) { if (isset($_FILES['fileToUpload'])) {
        $errors= array(); $file_name = $_FILES['fileToUpload']['name']; $file_size = $_FILES['fileToUpload']['size']; $width = 1500;
        $height = 1500; $file_tmp = $_FILES['fileToUpload']['tmp_name']; $file_type = $_FILES['fileToUpload']['type']; $tmp = explode('.',$_FILES['fileToUpload']['name']); $file_ext=strtolower (end ($tmp)); $extensions = array( "jpeg", "jpg", "png", "gif");

        if(in_array($file_ext,$extensions)=== false){

            $errors[]="extension not allowed, please choose a JPEG or PNG file."; } if ($file_size > 8097152) {

            $errors[] = 'File size must be 2 MB'; } if ($width > 1500 || $height > 1500) { echo"File is to large"; } if(!$errors) {

            $userPic = md5($_FILES["fileToUpload"]["name"]) . $date_time . " " . $file_name;
            $profilePic = move_uploaded_file($file_tmp,"assets/images/profile_pics/" . $userPic); $file_path = "assets/images/profile_pics/" . $userPic; $stmt = $con->prepare("UPDATE users SET profile_pic = ? WHERE username = ?"); $stmt->bind_param('ss', $file_path, $username);
            $stmt->execute(); $stmt->close();

            header('Location: settings.php');
            exit();
 
        }
    }
} else {

    echo "Invalid Username";
}

?>

Réponses

5 LiamSorsby Aug 18 2020 at 21:13

Ceci est mon opinion personnelle, mais je dirais ceci:

  1. Le code doit être formaté, je regarderais personnellement PSR-12 car cette norme doit être suivie lorsque cela est possible.
  2. move_uploaded_file ne protège pas contre la traversée de répertoire. Vous devez utiliser basename sur $_FILES['fileToUpload']['tmp_name']et d'autres formes de validation
  3. Vérifier l'extension de fichier avec if(in_array($file_ext,$extensions)=== false)n'empêche pas un utilisateur de télécharger un fichier malveillant, il pourrait par exemple utiliser un octet magique pour tromper le serveur en lui faisant croire qu'il s'agit d'un certain type de fichier. Vous devriez jeter un œil à finfo et au premier exemple de téléchargement de fichiers
  4. Vous créez un tableau d'erreurs, qui est actuellement vérifié dans une instruction if et est ensuite jeté. Si vous ne prévoyez pas de l'utiliser, vous feriez peut-être mieux de simplement quitter la fonction plus tôt que de poursuivre l'exécution.
  5. En fonction de l'unicité du nom de fichier, vous voudrez peut-être utiliser quelque chose comme uniqid(mt_rand(), true)
  6. move_uploaded_file remplacera un fichier s'il existe déjà, vous voudrez peut-être vérifier qu'il existe avant d'écraser un fichier existant. En fonction de votre solution de dénomination, il est très peu probable que cela se produise, mais sous une charge élevée pendant de longues périodes, cela peut se produire plus souvent que vous ne le pensez.
  7. Vous utilisez, UPDATE users SET profile_pic = ? WHERE username = ?je suppose que cette valeur existe dans la base de données car l'utilisateur doit être connecté. Cependant, si vous n'êtes pas sûr que le champ existe ou non (je n'ai pas vu la base de données), je utiliser personnellement: INSERT INTO users (profile_pic, username) VALUES (?,?) ON DUPLICATE KEY UPDATE profile_pic=?, username=?cela s'insérera dans la table si la ligne n'existe pas mais la mettra à jour si c'est le cas.
  8. Vous avez défini une variable locale appelée largeur et hauteur et vous les comparez à la même valeur. Je suppose que cela visait à vérifier les dimensions réelles du fichier?

J'espère que cela aide d'une certaine manière :)