IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

urldecode sur $_GET


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut urldecode sur $_GET
    Bonjour,

    Juste pour confirmer :

    Si je fais urlencode($toto) sur une variable $toto passée avec la méthode GET dans un formulaire, il faut selon moi que je fasse à l'arrivée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    extract($_GET) ;
    $vrai_toto = urldecode($toto) ;
    ...
    En effet j'ai vérifié et ça marche.

    Mon souci c'est que j'ai vu écrit dans le manuel php : http://fr2.php.net/manual/fr/function.urldecode.php je cite :

    "Les superglobales $_GET et $_REQUEST sont déjà décodées. Utiliser urldecode() sur un élément de $_GET ou $_REQUEST peut avoir des conséquences inattendues et dangereuses. "

    Comme je suppose qu'ils ont raison, j'imagine que ce qu'ils disent est vrai si on utilise register_globals = ON mais pas si register_globals = OFF

    Est-ce qu'un expert peut confirmer que mon interprétation est la bonne ?

    Merci.

  2. #2
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Salut

    Comme la doc l'indique, les données reçues en get, post disponibles dans les tabeaux $_GET, $_POST sont déjà décodés, donc appliquer un urldecode() sur ces données c'est le faire 2 fois, c'est déjà inutile.

    Pour le coté sécurité, et bien si tu applique une 2ème fois un urldecode(), tu prends le risque de modifier certains caractères d'une donnée, et donc ne pas obtenir la valeur attendue.
    Déjà là, c'est source de bug, mais pire, c'est peut être ce qu'attendait le pirate, et que plus loin dans ton code en exploitant cette donnée que ça débouche sur un acte de piratage.

    De l'autre, concernant la directive register_global à ON, ceci est aussi un manque de sécurité, car toutes les données obtenue en GET, POST seront automatiquement converties en variables.
    Donc un paramètre envoyé en GET, comme index.php?toto=trucmuche, on obtiendra une variable $toto contenant trucmuche.
    Exploiter directement cette variable sans vérification au préalable est un manque de sécurité, et c'est malheureusement une pratique courante.

    Du coup, la communauté a décidé un jour de mettre cette directive par défaut à Off.
    Celle ci n'existera plus dans la version Php6 d'après ce qui est annoncée.


    Cependant, les hébergeurs ont évolués (donc RG Off par défaut), parmi ceux là certains n'offraient pas la possibilité de modifier le register_global, donc toujours à Off.
    Et bien le piège, c'est que certains projets tournant sur ces hébergeurs ont utilisés comme astuce d'utiliser cette fonction extract(), et l'appliquer sur GET et POST.
    Les projets pouvaient continuer de tourner grâce à ça, donc sans trop d'effort.
    Mais bien que le register_global soit à Off, ce n'est pas pour autant que ces projets là soient plus sécurisés, bien au contraire.


    Conclusion, tu exploite cette fonction extract(), et bien c'est déjà un manque de sécurité, ceci revient à simuler le register_global à On.
    Je te conseil d'exploiter le donnée telle quelles sont reçues, soit $_GET['toto'] ou $_POST['toto'] mais aussi, et surtout vérifier que le contenu soit conforme à celui attendu.
    Puis ne pas appliquer de urldecode().
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut
    Merci RunCodePhp pour ta réponse étayée.

    - OK pour ta remarque qu'il vaut mieux ne pas utiliser extract.

    - Par contre je ne comprends toujours pas pourquoi il ne faut pas faire de urldecode (comme le dit effectivement le site référencé) car dans mon code SI JE NE FAIS PAS urldecode CA NE MARCHE PAS! il me faut faire urldecode !!

    Je fais donc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    extract($_GET) ;
    echo $toto."<br>" ;
    $toto = urldecode($toto) ;
    echo $toto ;
    Sans quoi si $toto= "la lune" je reçois à l'écran :

    la+lune
    la lune

    Merci,

    JP

  4. #4
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Et si tu fais :
    tu obtiens quoi ?


    Ceci dit, tu continu d'exploiter extract().

    La doc dit ceci :
    Avertissement
    N'utilisez pas extract() sur des données inconnues, comme les données utilisateurs (i.e. $_GET, $_FILES, etc.).
    Si vous le faites, par exemple, pour rendre compatible un vieux code avec register_globals à Off de façon temporaire, assurez-vous d'utiliser l'une des constantes extract_type qui n'écrasent pas les valeurs, comme EXTR_SKIP. Sachez aussi que vous devez maintenant extraire dans le même ordre que celui défini dans variables_order du php.ini.
    Donc à par rendre compatible un vieux code, et temporairement, comme dit ci-dessus, je ne vois pas l'intérêt de le faire dans ton cas.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut
    idem ! si je n'utilise pas urldecode :
    echo $_GET['toto'] ;
    donne "la+lune"

    IL FAUT DONC FAIRE urldecode contrairement à ce que dit la doc ??!!

  6. #6
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    IL FAUT DONC FAIRE urldecode contrairement à ce que dit la doc ??!!
    Pas besoin de crier aussi fort ... on est pas sourd ...

    Il doit avoir une explication, il serait pas mal de le savoir, mais ça se justifie peut être, je ne dis pas.
    Pour le urldecode() en tout cas, pas pour le extract().

    De mémoire tout de même, j'ai jamais eu ce problème là, jamais rencontré ce phénomène, donc jamais eu l'occasion d'utiliser cette fonction urldecode().
    J'en conclu que tu dois te trouver dans un cadre particulier, mais je ne vois pas lequel.
    En tout cas la conversion/décodage ne se fait pas, or, ça le devrait.
    Mon réflexe serait de me tourner du coté du php.ini, mais je ne vois pas quelle directive serait concernée.
    Sinon, c'est peut être du coté de Apache.

    Faut peut être dire dans quel environnement tu te trouve.
    Local, distant ?
    versions : Apache, Php, le navigateur aussi.

    Puis de quelle manière transmet tu cette donnée (lien, formulaire), le contenu est il fait en Php ou en dur ?
    Mets y le code, c'est plus simple.

    Y a t'il des routines de codes qui peuvent être déclenchés avant d'exploiter le $_GET ?

    Bref, faut en dire plus pour espérer une explication.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut
    Merci pour ta réponse, mais je n'ai pas ta patience, tant pis j'abandonne provisoirement... j'essaierai de comprendre plus tard.

    A+
    JP

  8. #8
    Membre chevronné Avatar de nosferapti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 157
    Points : 1 895
    Points
    1 895
    Par défaut
    le problème est peut-être au début
    Citation Envoyé par jpguiche Voir le message
    si je fais urlencode($toto) sur une variable $toto passée avec la méthode GET dans un formulaire
    montre nous le code que tu utilises pour construire l'URL
    GNAP !

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut
    Le voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
     
    // Coté appelant :
    ...
    $theme = urlencode($theme) ;
    $region = urlencode($region) ;
    header("Location: D_sinscrire_a_session.php?theme=$theme&region=$region&id_opportunite=$id_opportunite") ;
    exit() ;
     
    // Coté  D_sinscrire_a_session.php :
     
    $theme = $_GET['theme'] ;
    $region = $_GET['region'] ;
    $id_opportunite = $_GET['id_opportunite'] ;
    //
    $theme = urldecode($theme) ; 
    $region = urldecode($region) ;
    Je n'ai pas besoin de faire urlencode sur la variable $id_opportunite car c'est un nombre, par contre je le fais sur $theme et $region car ce sont des chaînes avec des espaces...

    Une idée ?

  10. #10
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Fais un essai avec la fonction : rawurlencode(), c'est c'est peut être un problème de norme.
    Donc juste pour encoder la chaine, et théoriquement, il ne devrait pas être utile de décoder.

    Sinon, il y a la fonction http_build_query() qui contruit une URL à partir d'un tableau.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut
    J'ai fait l'essai avec rawurlencode... c'est pareil il faut quand meme décoder ...

  12. #12
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    j'ai fait l'essai avec rawurlencode... c'est pareil il faut quand meme décoder ...
    ben alors là ???

    As tu essayé d'encoder toutes l'URL ?
    Comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $url = rawurlencode('theme='.$theme.'&region='.$region.'&id_opportunite='.$id_opportunite);
    header('Location: D_sinscrire_a_session.php?'.$url);
    exit();
    Et sans encoder ? Ca donne quoi ?

    Même si ça à l'air cuit d'avance, si tu mets "en dur" l'encodage, cet exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    header('Location: D_sinscrire_a_session.php?toto=-%26-');
    Théoriquement, un echo $_GET['toto'] renvoie : -&-
    Si tu est toujours obligé de décoder, alors c'est qu'il y a vraiment quelque chose ailleurs, Php ou Apache.
    Mais je ne vois vraiment pas où.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  13. #13
    Membre émérite
    Avatar de Eric2a
    Homme Profil pro
    Technicien
    Inscrit en
    Septembre 2005
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Technicien

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 225
    Points : 2 411
    Points
    2 411
    Par défaut
    Salut,

    Un code pour tester...

    test.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <?php
    $txt	 = isset($_GET['txt'])?$_GET['txt']:'';
     
    // $txt = urlencode('Une chaine à tester ici'); // Tester éventuellement avec urlencode
     
    // $txt = rawurlencode('Une chaine à tester ici'); // Tester éventuellement avec rawurlencode
     
    $txt_url = urldecode($txt);
    $txt_raw = rawurldecode($txt);
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Test</title>
    </head>
    <body>
    <?php if($txt!==''){ ?>
    <dl>
    	<dt>Texte brut</dt>
    	<dd><?php echo htmlspecialchars($txt); ?></dd>
    	<dt>Avec urldecode</dt>
    	<dd><?php echo htmlspecialchars($txt_url); ?></dd>
    	<dt>Avec rawurldecode</dt>
    	<dd><?php echo htmlspecialchars($txt_raw); ?></dd>
    </dl>
    <?php } ?>
    <form action="test.php" method="get">
    	<p>
    		<label for="txt">Texte</label><br />
    		<input type="text" value="" id="txt" name="txt" />
    	</p>
    </form>
     
    </body>
    </html>

  14. #14
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Il y a un truc qui me vient à l'esprit, c'est le type mime de la page, mais au niveau de l'entête.
    Comme ça, pure hypothèse bien sûr, je dirait que le serveur effectue le décodage que si c'est une page HTML (type=text/html).

    Donc le type de cette page est elle HTML ? (la page D_sinscrire_a_session.php)
    Ca ne serait pas une page exploitée uniquement en Ajax par hasard ?
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut
    Bonne idée...effectivement j'incluais le header après le code en question.

    J'ai mis le header avant...avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'/>
    Mais cela ne change rien...

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 12
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par jpguiche Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
     
    // Coté appelant :
    ...
    $theme = urlencode($theme) ;
    $region = urlencode($region) ;
    header("Location: D_sinscrire_a_session.php?theme=$theme&region=$region&id_opportunite=$id_opportunite") ;
    exit() ;
     
    // Coté  D_sinscrire_a_session.php :
     
    $theme = $_GET['theme'] ;
    $region = $_GET['region'] ;
    $id_opportunite = $_GET['id_opportunite'] ;
    //
    $theme = urldecode($theme) ; 
    $region = urldecode($region) ;
    Simplement une remarque par rapport à l'utilisation de «Location:», selon la norme HTTP tu dois utiliser l'URL absolue.

    Citation Envoyé par jpguiche Voir le message
    Bonne idée...effectivement j'incluais le header après le code en question.

    J'ai mis le header avant...avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'/>
    Mais cela ne change rien...
    Les meta injectés via HTML peuvent être ignoré par le navigateur si Apache (ou PHP via header()) envoie l'en-tête. Essai d'ajouter (en php)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    header('Content-Type: text/html; charset=ISO-8859-1');
    Sinon tu peux nous fournir un dump de phpinfo(); et de print_r(apache_get_modules()); ? (L'idée est d'avoir la liste des modules installés).

  17. #17
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par Suisse00 Voir le message
    Simplement une remarque par rapport à l'utilisation de «Location:», selon la norme HTTP tu dois utiliser l'URL absolue.
    Oui mais ça fait très très longtemps que les navigateurs acceptent des url relatives


    Citation Envoyé par Suisse00 Voir le message
    Les meta injectés via HTML peuvent être ignoré par le navigateur si Apache (ou PHP via header()) envoie l'en-tête. Essai d'ajouter (en php)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    header('Content-Type: text/html; charset=ISO-8859-1');
    On peux même dire qu'une entête apache prend systématiquement le pas sur une entête HTML.
    Pour l'instant apache envoie encore par défaut des entêtes au format iso... donc c'est surtout quand on travaille en utf-8 qu'il est important d'indiquer une entête avec php


    @jpguiche
    Bah si c'est la note du manuel qui te fait peur, utilises rawurlencode puis rawurdecode, c'est pas la même norme que urlencode. Même si rawurdecode n'est pas toujours nécessaire je n'ai jamais eu de pb lors de son utilisation (après un rawurlencode bien sûr) et c'est la solution recommandée par rapport à urlencode.
    Sinon l'encodage se fait par le navigateur et les résultats peuvent être différents suivant le navigateur (surtout sur les anciens navigateurs)...

    A part ça juste pour info rawurlencode n'est pas prévu pour encoder une url entière et ça peut poser des pb. L'usage normal est d'encoder des variables séparément.

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Février 2010
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 122
    Points : 71
    Points
    71
    Par défaut
    Merci ABCIWEB, Suisse00 et RunCodePhp.
    Si je trouve la réponse à l'énigme, je viendrai mettre à jour cette discussion et je mettrai "résolu".

    A+
    jpguiche

Discussions similaires

  1. urldecode automatique sur $_GET ?
    Par jpguiche dans le forum Langage
    Réponses: 4
    Dernier message: 03/05/2010, 16h29
  2. [RegEx] Appliquer un urldecode sur toute les url d'une page
    Par Bruno.C dans le forum Langage
    Réponses: 8
    Dernier message: 10/12/2008, 17h24
  3. [Tableaux] $_GET urldecodé automatiquement ?
    Par zk dans le forum Langage
    Réponses: 3
    Dernier message: 14/06/2007, 11h44
  4. [SQL] Aide sur $_GET
    Par ZeRiL dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 09/05/2006, 11h25
  5. Message notic sur _Get
    Par Sylvain245 dans le forum Langage
    Réponses: 2
    Dernier message: 05/12/2005, 12h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo