Formulaire d'upload pas sécurisé
loki33
-
Colbi97 Messages postés 564 Date d'inscription Statut Membre Dernière intervention -
Colbi97 Messages postés 564 Date d'inscription Statut Membre Dernière intervention -
Bonjour, malgré les sécurité que j'ai mise en place sur mon formulaire d'upload j'arrive quand même a y télécharger des fichier php (renommer en jpg). les fichiers ne rentre pas dans ma BDD mais ils vont quand même dans mon dossier "image". comment les bloquer?
voici le code
merci
voici le code
if(!empty($_FILES))
{
$avatar = $_FILES['avatar'];
$avatar_name = $avatar['name'];
$ext = strtolower(substr(strrchr($avatar_name,'.'),1));
$ext_aut = array('jpg','jpeg','png');
function check_extension($ext,$ext_aut)
{
if(in_array($ext,$ext_aut))
{
return true;
}
}
$valid = (!check_extension($ext,$ext_aut)) ? false : true;
$erreur = (!check_extension($ext,$ext_aut)) ? 'Veuillez charger une image' : '';
if($valid)
{
$max_size = 2000000;
if($avatar['size']>$max_size)
{
$valid = false;
$erreur = 'Fichier trop gros';
}
}
if($valid)
{
if($avatar['error']>0)
{
$valid = false;
$erreur = 'Erreur lors du transfert';
}
}
if($valid)
{
$path_to_image = 'image/image';
$path_to_min = 'image/miniature';
$filename = rand (10000,50000);
$source = $avatar['tmp_name'];
$target = $path_to_image . $filename. '.'. $ext;
$mintarget = $path_to_min . $filename. '.'. $ext;
move_uploaded_file($source,$target);
if($ext == 'jpg' || $ext == 'jpeg') {$im = imagecreatefromjpeg($path_to_image.$filename.'.'.$ext);}
if($ext == 'png') {$im = imagecreatefrompng($path_to_image.$filename.'.'.$ext);}
$ox = imagesx($im);
$oy = imagesy($im);
$nx = 300;
$ny = floor($oy *($nx/$ox));
$nm = imagecreatetruecolor($nx,$ny);
imagecopyresized($nm, $im, 0,0,0,0, $nx,$ny,$ox,$oy);
imagejpeg($nm, $path_to_min.$filename.'.'.$ext);
$nom_image = $target.'' ;
$min = $mintarget.'' ;
$data= array(
'image'=>$nom_image,
'min'=>$min
);
$nb= $DB->insert("INSERT INTO images (image,min) VALUES (:image,:min)",$data);
header('Location:upload.php');
exit;
}
}
merci
A voir également:
- Formulaire d'upload pas sécurisé
- Whatsapp formulaire opposition - Guide
- Mode sécurisé samsung - Guide
- Formulaire de réclamation facebook - Guide
- Youtube upload - Télécharger - Diffusion
- Formulaire de reclamation instagram - Guide
6 réponses
Salut,
Une solution est de vérifier en plus le type MIME du fichier envoyé.
Pour cela tu peux utiliser une des fonctions suivantes :
- https://www.php.net/manual/fr/function.getimagesize.php
- https://www.php.net/manual/en/ref.fileinfo.php
- http://us3.php.net/manual/en/function.mime-content-type.php (deprecated)
Bonne journée
Une solution est de vérifier en plus le type MIME du fichier envoyé.
Pour cela tu peux utiliser une des fonctions suivantes :
- https://www.php.net/manual/fr/function.getimagesize.php
- https://www.php.net/manual/en/ref.fileinfo.php
- http://us3.php.net/manual/en/function.mime-content-type.php (deprecated)
Bonne journée
Bonjour
Tu vérifies bien le type de fichier, mais tu le recopies AVANT la vérification !
Sois logique, ne le recopie qu'après, s'il est bien d'un des types acceptés !
Tu vérifies bien le type de fichier, mais tu le recopies AVANT la vérification !
Sois logique, ne le recopie qu'après, s'il est bien d'un des types acceptés !
Bonjour,
Des fichiers php renommés en jpg ?
Là, effectivement, çà va passer ton test sur l'extension sans problème, la vérification du type MIME ne bloquera pas non plus ce fichier (basée sur l'extension aussi, en fait donc quand on change l'extension le type MIME change avec).
La seule solution serait d'ouvrir en lecture avec PHP chaque fichier reçu puis de chercher dedans la présence de balises de début de code (version "normale" <?php comme version "courte <?).
Mais pourquoi vérifier ? Sauf erreur de ma part, sans accès en modification au serveur, le fichier ne pourra pas être renommer pour remettre la bonne extension et donc le serveur web n'interprètera jamais le code contenu. Il y aura juste une image non lisible de stockée.
Des fichiers php renommés en jpg ?
Là, effectivement, çà va passer ton test sur l'extension sans problème, la vérification du type MIME ne bloquera pas non plus ce fichier (basée sur l'extension aussi, en fait donc quand on change l'extension le type MIME change avec).
La seule solution serait d'ouvrir en lecture avec PHP chaque fichier reçu puis de chercher dedans la présence de balises de début de code (version "normale" <?php comme version "courte <?).
Mais pourquoi vérifier ? Sauf erreur de ma part, sans accès en modification au serveur, le fichier ne pourra pas être renommer pour remettre la bonne extension et donc le serveur web n'interprètera jamais le code contenu. Il y aura juste une image non lisible de stockée.
quand on change l'extension le type MIME change avec
C'est faux :
affiche
L'extension Fileinfo de php ne se base pas sur l'extension du fichier pour déterminer le type mime.
C'est faux :
<?php
$finfo = finfo_open(FILEINFO_MIME);
var_dump(finfo_file($finfo, 'fichier_php.php'));
var_dump(finfo_file($finfo, 'fichier_php.jpg'));
var_dump(finfo_file($finfo, 'fichier_image.jpg'));
var_dump(finfo_file($finfo, 'fichier_image.php'));
finfo_close($finfo);
?>
affiche
string 'text/html; charset=us-ascii' (length=27)
string 'text/html; charset=us-ascii' (length=27)
string 'image/jpeg; charset=binary' (length=26)
string 'image/jpeg; charset=binary' (length=26)
L'extension Fileinfo de php ne se base pas sur l'extension du fichier pour déterminer le type mime.
Ah, OK, erreur de ma part, hier je n'avais pas mon poste de dev sous la main et j'ai répondu après test sous windows (oui, oui, shame on me) et là, sous windows, le fait de changer l'extension fait que l'OS détermine un nouveau type MIME.
Mais c'est vrai qu'avec PHP, il ne se trompe pas...
Et après test sous Linux, il n'y a pas d'erreur non plus, encore une fois windows prouve sa grande supériorité (humour inside)
Mais c'est vrai qu'avec PHP, il ne se trompe pas...
Et après test sous Linux, il n'y a pas d'erreur non plus, encore une fois windows prouve sa grande supériorité (humour inside)
Pitet->Bonjour et merci pour vos liens je vais lire ça! Quel fonction tu me conseille des 3? (la plus utile)
le père-> Bonjour avant de recopier l'image je mets bien la condition if(valid) (qui vérifie que l'extension est ok) donc je comprends pas trop votre remarque?
Colbi97 ->Bonjour , oui c'est ce qu'il me semblait il n'y a aucun moyen pour l'utilisateur malveillant d'activer son script a distance sans accès au serveur mais j'aurais aimé en être sur. donc du coup si je copie le code actuel sur mon site je suis bon niveau sécurité ? sachant que pratiquement tout mon site sera basé sur le partage d'image j'aurais l'air vraiment con si y a des failles!
bonne soirée a vous!!
le père-> Bonjour avant de recopier l'image je mets bien la condition if(valid) (qui vérifie que l'extension est ok) donc je comprends pas trop votre remarque?
Colbi97 ->Bonjour , oui c'est ce qu'il me semblait il n'y a aucun moyen pour l'utilisateur malveillant d'activer son script a distance sans accès au serveur mais j'aurais aimé en être sur. donc du coup si je copie le code actuel sur mon site je suis bon niveau sécurité ? sachant que pratiquement tout mon site sera basé sur le partage d'image j'aurais l'air vraiment con si y a des failles!
bonne soirée a vous!!
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Toutes mes excuses, j'avais lu trop vite et ma remarque n'est pas justifiée.
Par contre, en lisant plus attentivement cette fois, je vois que tu ne testes pas la valeur de $im. Si le fichier n'est pas une bonne image, ou s'il y a un quelconque problème, $im sera FALSE et il suffit de faire le imagecreatefromxxx à partir du fichier temporaire, et de ne faire le move_uploaded_file qu'après si tout va bien.
Petite remarque :
et ce serait bien de ne pas omettre le "return false;" dans check_extension
Par contre, en lisant plus attentivement cette fois, je vois que tu ne testes pas la valeur de $im. Si le fichier n'est pas une bonne image, ou s'il y a un quelconque problème, $im sera FALSE et il suffit de faire le imagecreatefromxxx à partir du fichier temporaire, et de ne faire le move_uploaded_file qu'après si tout va bien.
Petite remarque :
$valid = (!check_extension($ext,$ext_aut)) ? false : true;est un façon bien compliquée d'écrire
$valid = check_extension($ext,$ext_aut);
et ce serait bien de ne pas omettre le "return false;" dans check_extension
Bonjour, j'ai donc rajouté une sécurité en plus avec getimagesize comme vous me l'avez conseillé au début
Et hop miracle mon php renommé en jpg ne passe plus !
Par contre j'ai entendu dire que ce n'était pas efficace contre les gifs avec du code php a l'intérieur?
dans tout les cas les .gif ne font pas partit des extensions que j'autorise au début donc je devrais être ok non?
bonne journée.
if($valid){
if(isset ($_FILES['image']) && ($_FILES['image']['error']==0)):
list ($width,$height,$type,$attr)= getimagesize ($_FILES['image']['tmp_name']);
if (is_null($type) && $width==0 && $height==0):
$erreur = 'Votre image est un php petit malin';
$validate = false;
endif;
endif;
}
Et hop miracle mon php renommé en jpg ne passe plus !
Par contre j'ai entendu dire que ce n'était pas efficace contre les gifs avec du code php a l'intérieur?
dans tout les cas les .gif ne font pas partit des extensions que j'autorise au début donc je devrais être ok non?
bonne journée.
À priori, oui, l'upload d'image est maintenant sûr, par contre, tu dis : sachant que pratiquement tout mon site sera basé sur le partage d'image.
Dans ce cas, l'utilisation de imagecreatefromjpeg sans contrôle de l'orientation EXIF de l'image n'est pas judicieux car cette fonction ne prend pas en compte l'orientation EXIF des fichiers et par conséquent, une image qui serait tournée en utilisant les infos EXIF (méthode de rotation principale pour les appareils photos) apparaîtra systématiquement dans son orientation originelle.
Pour corriger ce défaut, tu peux utiliser une nouvelle fonction créée comme ceci :
Edit : je vois dans ton code
Dans ce cas, l'utilisation de imagecreatefromjpeg sans contrôle de l'orientation EXIF de l'image n'est pas judicieux car cette fonction ne prend pas en compte l'orientation EXIF des fichiers et par conséquent, une image qui serait tournée en utilisant les infos EXIF (méthode de rotation principale pour les appareils photos) apparaîtra systématiquement dans son orientation originelle.
Pour corriger ce défaut, tu peux utiliser une nouvelle fonction créée comme ceci :
<?phpSource du script : doc imagecreatefromjpeg sur php.net
function imagecreatefromjpegexif($filename)
{
$img = imagecreatefromjpeg($filename);
$exif = exif_read_data($filename);
if ($img && $exif && isset($exif['Orientation']))
{
$ort = $exif['Orientation'];
if ($ort == 6 || $ort == 5)
$img = imagerotate($img, 270, null);
if ($ort == 3 || $ort == 4)
$img = imagerotate($img, 180, null);
if ($ort == 8 || $ort == 7)
$img = imagerotate($img, 90, null);
if ($ort == 5 || $ort == 4 || $ort == 7)
imageflip($img, IMG_FLIP_HORIZONTAL);
}
return $img;
}
?>
Edit : je vois dans ton code
$filename = rand (10000,50000);mais tu ne gère pas le cas où ton nombre aléatoire serait le même qu'un nombre déjà sorti (et çà peux arriver plus souvent qu'on le crois...), par conséquent tu risque d'écraser accidentellement des images précédemment uploadées.