Piratage ; protection contre le 'remontage' dans l'arborescence

Résolu
evenkil Messages postés 35 Date d'inscription lundi 13 février 2006 Statut Membre Dernière intervention 15 avril 2014 - 20 sept. 2007 à 23:51
audayls Messages postés 373 Date d'inscription samedi 9 juillet 2005 Statut Membre Dernière intervention 11 août 2008 - 21 sept. 2007 à 21:08
Bonjour à tous,

Je suis en train de bricoler un ftp maison.

J'ai une variable $dossier qui donne le repertoire à afficher.
Ca ressemble à http://truc.com/index.php?dossier= images
Et là l'utilisateur peut voir tous les fichiers contenus dans le répertoire via readdir.

Cependant je ne veux pas que l'utilisateur puisse taper .. ou . afin de remonter dans mon ftp.
Exemple : http://truc.com/index.php?dossier=./../..

J'ai donc pensé à mettre cette ligne en début de page :
if ( preg_match ( '.' , $_GET['dossier'])){ echo 'Tentative de piratage';exit; } else { echo 'OK' ; }
Autrement dit, si l'utilisateur met un . dans l'url pour essayer de remonter le repetoire, ca bloque tout.

Or le problème, c'est que meme si le $_GET['dossier'] ne contient pas de ".", j'obtiens le message 'Tentative de piratage'
Exemple  http://truc.com/index.php?dossier =photos/rep1

Pouvez vous me dire que dois je faire pour que l'utilisateur ne puisse mettre des . dans la variable 'dossier' ?

Merci beaucoup pour votre aide.

Cordialement

7 réponses

audayls Messages postés 373 Date d'inscription samedi 9 juillet 2005 Statut Membre Dernière intervention 11 août 2008
21 sept. 2007 à 19:10
Salut,
"Or le problème, c'est que meme si le $_GET['dossier'] ne contient pas de ".", j'obtiens le message "Tentative de piratage"" C'est tout à fait normal car le point en expression réguliere représente tous les caractères, il faut donc l'échapper.
Ce qui donnera :
<?php
if (preg_match('`\.`', $_GET['dossier']) !== 0) exit('Tentative de piratage');
else echo 'OK' ;
?>

Enfin bon l'expression régulière n'est pas spécialement interessante dans ce contexte, un simple "strpos" devrait pouvoir suffir :
<?php
if (strpos($_GET['dossier'], '../') !== FALSE) exit('Tentative de piratage');
else echo 'OK';
?>

For every choice, a consequence (Fable)
3
LeNoyauDur Messages postés 35 Date d'inscription vendredi 14 septembre 2007 Statut Membre Dernière intervention 25 août 2008 1
21 sept. 2007 à 09:36
Alors essaie où de mettre un fichier index.php qui redirige vers ta page d'accueil dans tous tes dossiers. Ou sinon tu peux le protéger avec un fichier htaccess & htpassword (qui demandera un login et mot de passe)

I'd rather be insulted by you than someone i respect.
0
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
21 sept. 2007 à 10:30
Je ne sais pas ce que tu essaies de faire, mais a priori mettre une url comme variable POST/GET c'est moyen.
Si c'est vraiment ce que tu veux, modifies juste ta fonction preg, elle doit bloquer à cause du point de machin.com.
regarde aussi la fonction realpath( ), ça te sera peut-être utile un jour.
0
evenkil Messages postés 35 Date d'inscription lundi 13 février 2006 Statut Membre Dernière intervention 15 avril 2014
21 sept. 2007 à 15:50
Merci pour toutes vos réponses.

J'ai essayé avec un htacess, mais bizarement on peut remonter les repertoires, même en utilisant des login password differents pour les repertoires.

Je vais expliquer un peu mieu ce que je veux faire
Voici mon aborescence :
//rep1/rep2/rep3
Le but du script est det lister tous les fichiers contenus dans le repertoire 2.
L'utilisateur peut creer un dossier, et donc acceder au rep3 (index.php?dossier=rep2/rep3)
Le repertoire choisit est définit dans l'url

Cependant je ne veux pas qu'il puisse tape index.php?dossier=.. pour remonter au rep1

J'ai essayé la fonction realpath() mais sans succès.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
pysco68 Messages postés 681 Date d'inscription samedi 26 février 2005 Statut Membre Dernière intervention 21 août 2014 8
21 sept. 2007 à 18:58
Regarde  voir ce que tu peux faire avec la variable __FILE__
enfait il faudrait que tu compare __FILE__ avec realpath($_GET['dossier']) pour voir si l'utilisateur n'essai pas de remonter trop loin dans l'arborescence.... (un simple comptage du nombre de caractères devrait blocker le gros des essais.... maintenant ça laisse des trous.... enfin à toi de trouver ce serait sympa de poster la solution, ça peut toujours servire )

Bonne soirée

Developpement Web Yannic GraphiX | Mon CMS yArt et sa démo
0
evenkil Messages postés 35 Date d'inscription lundi 13 février 2006 Statut Membre Dernière intervention 15 avril 2014
21 sept. 2007 à 20:33
Excellent !
Aprés avoir testé les deux solution de audayls, la bonne est la première.
En effet avec la deuxième, l'utilisateur peut encore taper . ou ..
La seule exeption dans les deux cas, c'est lorsque l'utilisateur encore /, dans ce cas il suffit de faire deux conditions :
//protection contre le piratage
if (preg_match('`\.`', $_GET['dossier']) !== 0) exit('Tentative de piratage');
if (preg_match('`^/`', $_GET['dossier']) !== 0) exit('Tentative de piratage');

Merci encore à tous pour vos réponses précieuses.
0
audayls Messages postés 373 Date d'inscription samedi 9 juillet 2005 Statut Membre Dernière intervention 11 août 2008
21 sept. 2007 à 21:08
Olala tu es bien complexe XD
"../" Permet de revenir dans le dossier précédent (donc tu souhaites l'empecher, c'est compréhensible...)
"./" fait référence au dossier en cours... Or le dossier en cours est visible (il faut bien afficher quelque chose ) Donc pourquoi vouloir l'interdir ?

Sinon au lieu d'utiliser 2 expressions régulières tu peux toujours utiliser çà :
<?php
if (strpos($_GET['dossier'], './') !== FALSE OR strpos($_GET['dossier'], '../') !== FALSE OR strpos($_GET['dossier'], '/') === 0) exit('Tentative de piratage');
?>

For every choice, a consequence (Fable)
0
Rejoignez-nous