Upload PHP
accueil >
Cours >
PHP >
Upload PHP
Cours / tutoriel écrit le 17-06-2010 par sky
Exemple d'upload PHP
Upload php
L'upload en PHP est utilisé au travers du web en générale d'une façon très peux sécurisé (la plupart du temps, pas du tout sécurisé).
L'un des problèmes est le manque de mises en garde et d'exemples sécurisé d'upload PHP.
L'upload PHP n'est pas à prendre à la légère; On doit vraiment prendre en compte les risques de sécurités qu'il engendre.
Pour commencer, voici un exemple d'upload PHP très simple qui ne fais aucune vérification de sécurité.
Ne pas utiliser sur un site en production !
<form method="post" enctype="multipart/form-data" action="">
<input type="file" name="fichier" size="30">
<input type="submit" name="upload" value="Uploader">
</form>
<?php
// 1
if( isset($_POST['upload']) )
{
$content_dir = $_SERVER['DOCUMENT_ROOT'].'/upload_dir/';
// 2
if( !is_uploaded_file($_FILES['fichier']['tmp_name']) )
{
exit("Le fichier est introuvable");
}
// 3
if( !move_uploaded_file($_FILES['fichier']['tmp_name'], $content_dir . $_FILES['fichier']['name']) )
{
exit("Impossible de copier le fichier dans $content_dir");
}
echo "Le fichier a bien été uploadé";
}
?>
Explications :
1) On vérifie que le formulaire a bien été validé
2) Upload du fichir
3) déplacement du ficher de sen répertoire temporaire vers le répertoire d'upload de destination
Voyons maintenant un exemple d'
upload PHP sécurisé (du moins, beaucoup plus sécurisé)
On vérifie quoi en faite ?
Ceci dépend de vous et de ce que vous voulez en faire, qui va avoir accès aux fichier, etc... Mais en règle générale :
- Extension
- Poid
- Caractères spécials
Le code PHP d'upload sécurisé :
<form method="post" enctype="multipart/form-data" action="">
<input type="file" name="fichier" size="30">
<input type="submit" name="upload" value="Uploader">
</form>
<?php
if($_POST['upload'])
{
// repertoire où vont être placé les fichiers
$content_dir = $_SERVER['DOCUMENT_ROOT'].'/upload_dir/';
// ajouter ici les autres extensions autorisé
$extensions_OK = array('jpg', 'jpeg', 'gif', 'png', 'pdf', 'doc', 'docx', 'etc...');
// Le nom du fichier ne peux pas être vide
if(empty($_FILES['fichier']['name'])){
exit("Aucun fichier sélectionné.");
}
// on test si le fichier est uploadé
if( !is_uploaded_file($_FILES['fichier']['tmp_name']) ){
exit("Le fichier n'a pas pu être uploadé.");
}
// récupération de l'extension du fichier
$ext = strtolower( pathinfo($_FILES['fichier']['name'], PATHINFO_EXTENSION) );
// est ce que l'extension est valide ?
if(!in_array($ext, $extensions_OK)) {
exit("Le format de votre fichier n'est pas autorisé.");
}
// renommons le fichier pour plus de sécurité
// ceci donne un nom de fichier très dur à trouver
$name_file = md5( uniqid('H', 5) ).'.'.$ext;
// upload
if(!move_uploaded_file($tmp_file,$content_dir.$name_file)){
exit("Impossible de copier le fichier !");
}else{
echo "Le fichier a bien été uploadé";
}
}
?>
Dans cette exemple, on vérifie que le nom du fichier n'est pas vide, que l'extension est bien valide.
Puis, on le renomme pour avoir un nom de fichier très dur à trouver.
Et maintenant, une fonction PHP d'upload avec une utilisation très simple !
<?php
function upload($_files, $destination_rep)
{
if(!empty($_files['fichier']['tmp_name']) && !empty($_files['fichier']['name']))
{
$tmp_file = $_files['fichier']['tmp_name'];
//on test si l'upload a reussi
if(!is_uploaded_file($tmp_file))
exit('Erreur lors de l\'upload.');
// on va ajouter une chaine pour rendre le nom du fichier unique et pratiquement introuvable.
$unikifier = md5( uniqid('H', 5) );
// extension du fichier
$ext = pathinfo($_FILES['fichier']['name'], PATHINFO_EXTENSION);
// nettoyage du nom du fichier (on peux pas d'accents ou d'espace)
$file_name = $unikifier.'.'.$ext;
//on déplace le fichier vers notre répertoire de destination
if(!move_uploaded_file($tmp_file, $destination_rep.$file_name))
exit("Impossible de déplacer le fichier. Upload annulé.");
else
return $file_name;
}
}
$file_dir = './upload_dir/';
if($_POST || $_FILES)
{
$file = upload($_FILES, $file_dir);
echo 'Upload terminé : '.$file;
}
else
{
echo '
<form method="post" enctype="multipart/form-data" action="">
<input type="file" name="fichier" size="30">
<input type="submit" name="upload" value="Uploader">
</form>';
}
?>
On pourrai allez plus loin ? OUI !
Il faudrai définir le répertoire d'upload dans un endroit NON accéssible depuis un navigateur web,
renommer complètement le fichier, vérifié que le fichier ne contient pas (DANS le fichier) du code PHP ou autre, vérifié le type MIME et faire une contre vérification avec l'extension. Mais bon, ceci est abordé dans le script
d'
upload sécurisé myPHPupload
Bon upload php !
Commentaires
FeN_X le 23-11-2010
Comme dev l'a dit, il manque cette ligne :
$tmp_file = $_FILES['fichier']['tmp_name'];
De plus, si on upload un fichier .jpg contenant du code PHP, ce dernier peut être exécuté en passant par une LFI (un include mal sécurisé).
D'accord, ça n'arrive pas toujours, mais ça arrive.
Il faudrait créer une image à partir du fichier (imagecreatefrom*)
Cela dit, il y a de l'idée
dev le 07-09-2010
Dans votre exemple : Le code PHP d'upload sécurisé, la variable $tm_file n'est pas affectée, l'upload est impossible.