Sécuriser un script php de téléchargement de fichiers

Ithri-2B
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 20
Inscription: 13 Mar 2009

Sécuriser un script php de téléchargement de fichiers

Message le Ven Mar 13, 2009 16:00

Bonjour tout le monde,

Je viens de me rendre compte qu'un script php de mon site comporte une énorme faille. Le script en question permet de lancer le téléchargement de fichiers images (.jpg et .png), mais à ma grande stupeur je viens de voir qu'il peut lancer n'importe quel fichier qui se trouve sur le site (fichiers php html même le htaccess 8O ) enfin bref, la brèche du siècle quoi :) j'ai bien entendu retiré ce script en attendant de le sécuriser.

Ce script utilise une variable avec la fonction GET pour récupérer les chemins de fichiers à télécharger. Je souhaite donc interdire à la variable qui utilise la fonction GET, de ne pas traverser tous les répertoires, sauf celui qui contient les images. Comment je pourrais faire pour cela ?

Voici le code ce script :

Code: Tout sélectionner
<?PHP
foreach ($_REQUEST as $key => $val)
{
  $val = preg_replace("/[^_A-Za-z0-9-\.&=]/i",'', $val);
  $_REQUEST[$key] = $val;
}

$fichier = $_GET['jpg_png'];

$nom = basename($fichier);
header("Content-disposition: attachment; filename=$nom" );
header("Content-Type: image/jpeg" );
header("Content-Transfer-Encoding: binary" );
header("Pragma: no-cache" );
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" );
header("Expires: 0" );
readfile($fichier);
?>


Merci pour tout.


forty
WRInaute passionné
WRInaute passionné
 
Messages: 1701
Inscription: 30 Oct 2008

Re: Sécuriser un script php de téléchargement de fichiers

Message le Ven Mar 13, 2009 16:46

je te conseille déjà d'utiliser la fonction realpath pour récupérer le vrai chemin du fichier (sans ../). après tu utilises un preg_match pour vérifier que c'est dans le bon répertoire avec la bonne extension.

Ithri-2B
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 20
Inscription: 13 Mar 2009

Re: Sécuriser un script php de téléchargement de fichiers

Message le Ven Mar 13, 2009 17:00

forty a écrit:je te conseille déjà d'utiliser la fonction realpath pour récupérer le vrai chemin du fichier (sans ../). après tu utilises un preg_match pour vérifier que c'est dans le bon répertoire avec la bonne extension.


Merci pour ta réponse,

Je suis un débutant en php, tu pourras m'expliquer comment mettre ces fonctions en place ?


forty
WRInaute passionné
WRInaute passionné
 
Messages: 1701
Inscription: 30 Oct 2008

Re: Sécuriser un script php de téléchargement de fichiers

Message le Ven Mar 13, 2009 17:16

tu peux déjà essayer de comprendre comment elles marchent : -http://fr.php.net/realpath
et -http://fr.php.net/preg_match

pour vérifier que le fichier est dans le bon répertoire avec la bonne extension tu peux utiliser :
Code: Tout sélectionner
if (preg_match('/^' . preg_quote('/home/tonsite/le_bon_repertoire/', '/') . '[a-zA-Z0-9]+\.jpg$/', $fichier)) {
...
}

ce code va vérifier que le nom du fichier est de la forme /home/tonsite/le_bon_repertoire/unnom.jpg avec "unnom" qui ne peut contenir que des lettres ou des chiffres.

Ithri-2B
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 20
Inscription: 13 Mar 2009

Re: Sécuriser un script php de téléchargement de fichiers

Message le Sam Mar 14, 2009 0:06

Merci pour ces explications, j'ai essayé la condition "if", elle ne marche pas si je met le répertoire, en revanche si je ne met pas de répertoire ça marche, c'est bizarre non ?

Ce code marche :
Code: Tout sélectionner
if (preg_match('/^' . preg_quote('', '/') . '[_a-zA-Z0-9-]+\.jpg$/', $fichier)) {
$bla = $bla2;
}


Le code qui ne marche pas :

Code: Tout sélectionner
if (preg_match('/^' . preg_quote('/home/tonsite/le_bon_repertoire/', '/') . '[_a-zA-Z0-9-]+\.jpg$/', $fichier)) {
$bla = $bla2;
}


J'ai vérifié à plusieurs reprises le chemin et le nom du fichier, tout est bon, mais ça ne marche pas :(


forty
WRInaute passionné
WRInaute passionné
 
Messages: 1701
Inscription: 30 Oct 2008

Re: Sécuriser un script php de téléchargement de fichiers

Message le Sam Mar 14, 2009 8:46

tu peux aussi passer en paramètre que le nom de fichier et ajouter toi même le répertoire. C'est plus simple et plus sécurisé.
dans ce cas tu vérifies qu'il n'y a que des caractères autorisés dans le nom de fichier et la bonne extension :
Code: Tout sélectionner
if (preg_match('/^[_a-zA-Z0-9-]+\.jpg$/', $parametre_image_sans_répertoire)) {
    $fichier = '/chemin/du/repertoire/image/' . $parametre_image_sans_répertoire;
    //ton traitement
}

tu peux aussi baser le chemin par rapport au répertoire du script courant avec dirname(__FILE__) :
Code: Tout sélectionner
$fichier = dirname(__FILE__) . '/image/' . $parametre_image_sans_répertoire;

Ithri-2B
Nouveau WRInaute
Nouveau WRInaute
 
Messages: 20
Inscription: 13 Mar 2009

Re: Sécuriser un script php de téléchargement de fichiers

Message le Dim Mar 15, 2009 0:55

Bonsoir,

Merci beaucoup ça marche super bien, et pour sécuriser encore un peu les choses et cacher les variables sans pas par GET ou POST, j'ai opté pour la fonction $_SESSION pour véhiculer mes variables :-).


Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 0 invités