PDO et syntaxe

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : PDO et syntaxe

Re: PDO et syntaxe

par sam01 » 09 mars 2015, 14:47

OK.
C'est noté.

Merci.

Re: PDO et syntaxe

par AB » 06 mars 2015, 19:32

Le problème est que quote() est prévue pour protéger les valeurs des champs, non pas les valeurs des noms des champs.
Et donc cette fonction rajoute des quotes en début et en fin de chaine. Concrètement si lang = fr, alors 'cont_'.$db->quote($lang) va retourner cont_'fr'.
Dans ce cas particulier, tu pourrais t'en tirer en utilisant la fonction trim :
$champ = 'cont_'.trim($db->quote($lang),"'");
Pour la protection des noms des champs il faut utiliser les quotes obliques. Tu pourrais donc faire
$champ = 'cont_'.trim($db->quote($lang),"'");
$query = "SELECT `".$champ."` FROM flatforswap_continent ORDER BY `".$champ."` ASC";
$sqla = $db->query($query);
Peut-être que les quotes obliques suffiraient à elles seules pour la protection du nom des champs. Comme je n'ai pas vraiment cherché de réponse (car comme déjà dit quand j'ai des champs dynamiques, je teste la validité de ces champs juste avant de faire la requête) j'adopterais plutôt la syntaxe ci-dessus car cette double protection ne devrait pas poser de problème.

Re: PDO et syntaxe

par sam01 » 06 mars 2015, 11:46

Ca devrait être bon là

Code : Tout sélectionner

$sqla = $db->query("SELECT cont_".$db->quote($lang)." FROM flatforswap_continent ORDER BY cont_".$db->quote($lang)." ASC"); while($dataa = $sqla->fetch()) { if ($continent == $dataa['cont_'.$lang.'']) { echo '<option value="'.$dataa['cont_'.$lang.''].'" selected="selected">'.$dataa['cont_'.$lang.''].'</option>'; } if ($continent != $dataa['cont_'.$lang.'']) { echo '<option value="'.$dataa['cont_'.$lang.''].'">'.$dataa['cont_'.$lang.''].'</option>'; } }

Re: PDO et syntaxe

par AB » 05 mars 2015, 18:20

Je me répond à moi-même :

Cela dit quand on modifie le nom d'un champ avec une variable, il est normalement "toujours" possible de contrôler si le nom du champ est correct avant de faire la requête. Et si par ailleurs on utilise les requêtes préparées dès qu'il s'agit de lier des valeurs aux variables (excepté les noms des champs), cela explique pourquoi je n'utilise quasiment jamais la fonction quote().

Re: PDO et syntaxe

par AB » 05 mars 2015, 18:08

Oui donc tu ne risque pas d'injection.
Enfin bon cela ne te dispense pas de faire la requête correctement avec la protection quote sur $lang, comme ça tu sauras le faire (c'est assez souvent qu'on ne peut pas contrôler la variable avant).

Re: PDO et syntaxe

par sam01 » 05 mars 2015, 17:48

Au fait la variables $lang est définiie en amont de mon code (elle est donc forcément vérifiée puisque c'est moi qui l'impose)

Code : Tout sélectionner

$domaines_config = array( 'www.example.com' => 'en', 'www.example.fr' => 'fr', 'www.example.es' => 'es' ); // $domaine = ''; $lang = ''; // On vérifie que le domaine if ( isset($domaines_config[$_SERVER['HTTP_HOST']] ) ) { $lang = $domaines_config[$_SERVER['HTTP_HOST']] ; } else { echo 'Domaine non reconnu'; exit(); // throw new Exception("Domaine non reconnu:".$_SERVER['HTTP_HOST']); }

Re: PDO et syntaxe

par AB » 05 mars 2015, 17:19

Effectivement c'est typiquement le cas où les requêtes préparées ne servent à rien car les marqueurs ne peuvent se lier qu'aux valeurs des champs et non pas au nom des champs. Ainsi tu faisais une requête préparée qui n'était pas sécurisée. Avec query ou exec il faut utiliser quote pour protéger la chaine de la requête.

Cela dit normalement tu dois bien avoir un tableau de traduction des langues. Et dans le cas il te suffit de faire

Code : Tout sélectionner

if(in_array($lang, $tab_lang)) {//requête}
Pour dire qu'à chaque fois que cela est possible, requête préparée ou pas, on vérifie toujours si la variable fournie fait partie des variables attendues avant de faire une requête.

Re: PDO et syntaxe

par sam01 » 05 mars 2015, 17:13

es-tu sûr que je m'expose aux injections...

Je ne vois pas comment une injection peut rentrer dans ce code...

Re: PDO et syntaxe

par xTG » 05 mars 2015, 16:53

Tu t'exposes toujours aux injections.
Regardes mon exemple utilisant query ET SURTOUT l'utilisation de quote. ;)

Re: PDO et syntaxe

par sam01 » 05 mars 2015, 16:50

OK.

j'ai effectivement été attaqué par injection mysql. certaines de mes tables ont complètement été vidées.
J'ai donc décidé de mettre à jour mon site en intégrant du PDO.
Si j'ai bien compris, et en tenant compte de vos remarques, voici ce que donne mon code :

Code : Tout sélectionner

$sqla = $db->query("SELECT cont_".$lang." FROM flatforswap_continent ORDER BY cont_".$lang." ASC"); while($dataa = $sqla->fetch()) { if ($continent == $dataa['cont_'.$lang.'']) { echo '<option value="'.$dataa['cont_'.$lang.''].'" selected="selected">'.$dataa['cont_'.$lang.''].'</option>'; } if ($continent != $dataa['cont_'.$lang.'']) { echo '<option value="'.$dataa['cont_'.$lang.''].'">'.$dataa['cont_'.$lang.''].'</option>'; } }
etc-ce que ça vous semble correct ?

Re: PDO et syntaxe

par AB » 05 mars 2015, 16:45

J'avais pas vu le message d'xTG...

Voici donc quelques explications concernant nos "différentes versions" :

Il faut savoir qu'à l'origine les requêtes préparées sont prévues pour accélérer le processus d'exécution des requêtes multiples, typiquement dans une boucle.

Ensuite il s'avère que les requêtes préparées sont plus sécurisées contre les infections sql car la préparation de la requête fait une abstraction (bind) entre le symbol et la variable et donc la variable ne fait pas partie directement de la chaine de la requête. Comme le coût de la préparation n'est pas très élevé en terme de performance on conseille donc d'utiliser les requêtes préparées pratiquement à chaque fois que l'on traite des variables utilisateurs.
Ensuite pour pas se prendre le choux, on peut aller jusqu'à dire à chaque fois que l'on traite une variable.

Mais si j'ai bien compris vous voulez utiliser des requêtes préparées systématiquement même sans variables. Là vous poussez le bouchon un peu loin. Et puis vous passez à côté des fonctionnalités pratiques des fonctions exec et query que ne possède pas execute.

Re: PDO et syntaxe

par AB » 05 mars 2015, 16:18

Normalement on utilise une requête préparée pour lier des variables dans une requête.
Donc on fait un prepare(), on bind les variables individuellement et on utilise execute() sans paramètre,
ou,
on fait un prepare() et on bind les variables globalement en passant un tableau comme paramètre dans le execute($array).

Quand il n'y a pas de variable à lier dans la requête, l'étape du prepare() n'est pas justifiée.
Dans ce cas on utilise juste query() pour les sélections et exec() pour les autres (update, insert, delete)

Re: PDO et syntaxe

par xTG » 05 mars 2015, 16:05

Non... Si tu ne passes rien tu ne fais pas de requête préparée du tout.
Sinon c'est comme utiliser une pelleteuse 40t pour retourner ton parterre de fleur de 2m², cela ne sert à rien... :P

Voici quelques exemples d'utilisation (et encore qui pourraient se discuter).
Requête préparée car utilisée plusieurs fois :
foreach($liste as $champs3)
{
   $sql = $db->prepare("SELECT champs1, champs2 FROM maTable WHERE champs3 = ? AND date > NOW()");
   $sql->execute(array($champs3));
   // traitement ....
}
Un cas de requête unique qui ne requiert donc pas de requête préparée :
$sql = $db->query("SELECT champs1, champs2 FROM maTable WHERE champs3 = " . $db->quote($champs3));
La fonction quote est là pour protéger la requête contre les injections.
Note : dans le cas d'une requête préparée c'est directement géré par la fonction execute.

Re: PDO et syntaxe

par tof73 » 05 mars 2015, 15:43

le execute sert à exécuter ta requête, étape indispensable.
selon que tu as des paramètres à lier, tu passes un tableau avec du contenu, un tableau vide, ou rien.

Re: PDO et syntaxe

par sam01 » 05 mars 2015, 15:40

Bonjour,

mais alors à quoi sert le

Code : Tout sélectionner

$sqla->execute(array());
?

Dans la requête suivante, par exemple, j'utilise le ->execute(array())

Code : Tout sélectionner

$sql = $db->prepare("select * from fcadsd_adh where mail=? and mdp=? and valide !=?"); $sql->execute(array($mail, $mdp, '0'));