Espace membres

Bonjour Anonyme

Inscription

Email :
Mot de passe :

Mot de passe oublié ?

Nos scripts

MySpeach

MySpeach est un chat php sans base de donnée, rapide, léger et facile à prendre en main. DEMO

MyPHPUpload

MyPHPUpload est un script d'upload sécurisé écrit en PHP. DEMO

GrapAgenda

Agenda PHP et MySQL avec comptes utilisateurs et administration. DEMO

Livre PHP

création de site

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.

Pseudo
Email
Commentaire

Merci d'écrire le code ici :