Je ne sais pas si cela va se produire, mais je vais essayer.
Pendant l'heure écoulée, j'ai fait des recherches sur la sécurité de téléchargement d'images. J'ai appris qu'il existe de nombreuses fonctions pour tester le téléchargement.
Dans mon projet, j'ai besoin d'être prudent avec les images téléchargées. Il pourrait aussi y avoir une très grande quantité et cela pourrait nécessiter beaucoup de bande passante, donc acheter une API n'est pas une option.
Alors j'ai décidé d'obtenir un script PHP complet pour un téléchargement d'images VRAIMENT sécurisé. Je pense aussi que cela aidera de nombreuses personnes, car il est impossible de trouver une solution vraiment sécurisée. Mais je ne suis pas un expert en php, donc c'est vraiment un casse-tête pour moi d'ajouter certaines fonctions, donc je vais demander de l'aide à cette communauté pour créer un script complet de téléchargement d'images VRAIMENT sécurisé.
De bons sujets sur cela sont ici (cependant, ils disent simplement ce qu'il faut faire, mais pas comment le faire, et comme je l'ai dit, je ne suis pas un maître en PHP, donc je ne suis pas capable de le faire tout seul) : Liste de vérification de sécurité du téléchargement d'images PHP https://security.stackexchange.com/questions/32852/risks-of-a-php-image-upload-form
En résumé, ils disent que c'est ce qui est nécessaire pour un téléchargement d'images sécurisé (je vais citer les pages ci-dessus) :
- Désactiver l'exécution de PHP à l'intérieur du dossier de téléchargement en utilisant .httaccess.
- Ne pas autoriser le téléchargement si le nom du fichier contient la chaîne "php".
- Autoriser uniquement les extensions : jpg, jpeg, gif et png.
- Ne permettre que le type de fichier image.
- Interdire les images avec deux types de fichiers.
- Changer le nom de l'image. Charger dans un sous-répertoire et non dans le répertoire racine.
Aussi :
- Re-traiter l'image en utilisant GD (ou Imagick) et enregistrer l'image traitée. Tout le reste est juste ennuyeux pour les pirates
- Comme l'a souligné rr, utilisez move_uploaded_file() pour tout téléchargement
- Au fait, vous voulez être très restrictif concernant votre dossier de téléchargement. Ce sont l'un des coins sombres où de nombreuses failles se produisent. Cela est valable pour tout type de téléchargement et tout langage/serveur de programmation. Consultez https://www.owasp.org/index.php/Unrestricted_File_Upload
- Niveau 1 : Vérifiez l'extension (le fichier d'extension se termine par)
- Niveau 2 : Vérifiez le type MIME ($file_info = getimagesize($_FILES['image_file']; $file_mime = $file_info['mime'];)
- Niveau 3 : Lisez les 100 premiers octets et vérifiez s'ils contiennent des octets dans la plage suivante : ASCII 0-8, 12-31 (décimal).
- Niveau 4 : Vérifiez les nombres magiques dans l'en-tête (10 à 20 premiers octets du fichier). Vous pouvez trouver certains des octets d'en-tête des fichiers dans ce lien : http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Examples
- Vous voudrez peut-être exécuter "is_uploaded_file" sur le $_FILES['my_files']['tmp_name'] également. Voir http://php.net/manual/en/function.is-uploaded-file.php
Voici une grande partie, mais ce n'est pas tout. (Si vous avez des informations supplémentaires qui pourraient aider à rendre le téléchargement encore plus sécurisé, veuillez les partager).
CE QUE NOUS AVONS MAINTENANT
-
Code PHP principal :
function uploadFile ($file_field = null, $check_image = false, $random_name = false) { //Section de configuration //Définir le chemin de téléchargement du fichier $path = 'uploads/'; //avec une barre oblique finale //Définir la taille maximale du fichier en octets $max_size = 1000000; //Définir la liste blanche par défaut des extensions de fichiers $whitelist_ext = array('jpeg','jpg','png','gif'); //Définir la liste blanche par défaut des types de fichiers $whitelist_type = array('image/jpeg', 'image/jpg', 'image/png','image/gif'); //La Validation // Créer un tableau pour contenir toute sortie $out = array('error'=>null); if (!$file_field) { $out['error'][] = "Veuillez spécifier un nom de champ de formulaire valide"; } if (!$path) { $out['error'][] = "Veuillez spécifier un chemin de téléchargement valide"; } if (count($out['error'])>0) { return $out; } //S'assurer qu'il y a un fichier if((!empty($_FILES[$file_field])) && ($_FILES[$file_field]['error'] == 0)) { // Obtenir le nom de fichier $file_info = pathinfo($_FILES[$file_field]['name']); $name = $file_info['filename']; $ext = $file_info['extension']; //Vérifier que le fichier a la bonne extension if (!in_array($ext, $whitelist_ext)) { $out['error'][] = "Extension de fichier non valide"; } //Vérifier que le fichier est du bon type if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) { $out['error'][] = "Type de fichier non valide"; } //Vérifier que le fichier n'est pas trop grand if ($_FILES[$file_field]["size"] > $max_size) { $out['error'][] = "Le fichier est trop gros"; } //Si $check image est défini sur true if ($check_image) { if (!getimagesize($_FILES[$file_field]['tmp_name'])) { $out['error'][] = "Le fichier téléchargé n'est pas une image valide"; } } //Créer un nom de fichier complet incluant le chemin if ($random_name) { // Générer un nom de fichier aléatoire $tmp = str_replace(array('.',' '), array('',''), microtime()); if (!$tmp || $tmp == '') { $out['error'][] = "Le fichier doit avoir un nom"; } $newname = $tmp.'.'.$ext; } else { $newname = $name.'.'.$ext; } //Vérifier si le fichier existe déjà sur le serveur if (file_exists($path.$newname)) { $out['error'][] = "Un fichier portant ce nom existe déjà"; } if (count($out['error'])>0) { //Le fichier n'a pas été correctement validé return $out; } if (move_uploaded_file($_FILES[$file_field]['tmp_name'], $path.$newname)) { //Succès $out['filepath'] = $path; $out['filename'] = $newname; return $out; } else { $out['error'][] = "Erreur de serveur !"; } } else { $out['error'][] = "Aucun fichier téléchargé"; return $out; } } if (isset($_POST['submit'])) { $file = uploadFile('file', true, true); if (is_array($file['error'])) { $message = ''; foreach ($file['error'] as $msg) { $message .= ''.$msg.''; } } else { $message = "Fichier téléchargé avec succès".$newname; } echo $message; }
-
Et le formulaire :
Donc, ce que je demande, c'est de l'aide en postant des extraits de code qui m'aideront (et aideront tout le monde) à rendre ce script de téléchargement d'images vraiment sécurisé. Ou en partageant/créant un script complet avec tous les extraits ajoutés.
1 votes
Depuis que je reçois des votes positifs sur ma réponse à celle-ci, permettez-moi d'expliquer les votes négatifs sur votre question : Stack Overflow est un endroit pour trouver de l'aide si vous avez des problèmes avec votre code. Ce n'est pas un endroit pour améliorer du code qui fonctionne (Code Review est le site Web pour cela), et ce n'est pas non plus un endroit pour trouver ou demander des tutoriels. Simplement parce que (comme vous le voyez), il faut écrire la moitié d'un livre pour donner une réponse correcte et complète. Le nombre de vues est simplement parce que vous avez offert une prime dessus. Pas parce que tout le monde en a besoin :)
3 votes
@icecub Je suis sûr qu'il y a encore des personnes qui cherchent cette réponse et qui sont contentes que vous l'ayez donnée.
0 votes
Oui, il semble que beaucoup de personnes y fassent référence dans d'autres questions car beaucoup de gens ne réalisent pas que leurs scripts de téléchargement ne sont pas sécurisés. Je ne m'attendais pas à obtenir autant de votes positifs cependant. C'est assez rare de nos jours.
5 votes
Merci pour la question Simon. Tu as mon vote. J'ai dû chercher partout sur le web des informations que tu as déjà compilées dans ta question.
0 votes
@AuntJamaima Merci tante, je suis heureux que cela vous ait aidé
0 votes
if (!in_array($_FILES[$file_field]["type"], $whitelist_type)) {
Est-ce une bonne pratique ?2 votes
Dommage que ne soit pas complètement sécurisé et soit vulnérable aux attaques de script entre sites.