[resolved] PDO et la sécurité

PDO et la sécurité [resolved] - PHP - Programmation

Marsh Posté le 12-04-2011 à 20:48:03    

Bonsoir
 
Je travaille sur un projet PHP / Mysql. Je lis partout qu'il ne faut pas faire confiance aux données reçues par l'utilisateur et qu'il faut les contrôler avant de mettre à jour la base de données, avec mysql_real_escape_string (par exemple).  
 
Ma question : est ce qu'il faut le faire même si la requête est "préparée" avec PDO ? Ou serait ce du luxe ?  
 
Merci d'avance pour vos réponse.  
 
Dominique
(néophyte en sécurité)


Message édité par domi_bu le 13-04-2011 à 19:25:29
Reply

Marsh Posté le 12-04-2011 à 20:48:03   

Reply

Marsh Posté le 12-04-2011 à 21:33:59    

Pas besoin. Utilise PDO et laisse le gérer le tout :)


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 13-04-2011 à 10:44:02    

Oui, il faut contrôler et échapper les données.
 
* Les contrôles consistent à s'assurer que les données ont :
 
- la bonne taille,
- le bon type,
- les bonnes valeurs permises,
- éventuellement, supprimer les espaces au début ou en fin de chaîne.
 
* "Echapper" les données est absolument nécessaire, et d'ailleurs, c'est indiqué en clair et en souligné dans la documentation :

Citation :

Les données contenues dans la requête doivent être échappées proprement.
 
(source : http://www.php.net/manual/fr/pdo.query.php , paragraphe "Liste de paramètres" )

L'échappement consiste à :
 
- remplacer les apostrophes par des doubles apostrophes,
- remplacer éventuellement les caractères non imprimables tels que les éventuels retours chariots par des caractères acceptables pour le type de champ de destination,
- convertir les caractères qui sont exotiques par rapport au jeu de caractères attendu par la base (par exemple, les caractères accentués, etc.).

Reply

Marsh Posté le 13-04-2011 à 10:56:23    

Sauf que si on lit la doc jusqu'au bout :
 

Citation :


Si vous utilisez cette fonction pour construire des requêtes SQL, vous êtes vivement invités à utiliser PDO::prepare() pour préparer les requêtes SQL avec des paramètres liés au lieu d'utiliser PDO::quote() pour interpréter les entrées utilisateur dans la requête SQL. Les requêtes préparées avec des paramètres liés sont non seulement plus portables, plus souples et plus sécuritaires, mais bien plus rapides à exécuter que d'interpréter les requêtes, étant donné que les côtés client et serveur peuvent mettre en cache une version compilée de la requête.  


 
Moralité => Utiliser PDO intelligemment et le laisser gérer le tout.


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 13-04-2011 à 11:11:10    

Le texte cité n'est pas en contradiction avec la phrase que j'ai citée plus haut (et heureusement, sinon la documentation serait incohérente).
Le texte cité n'a pas de rapport avec l'échappement, qui, je le maintiens, est absolument nécessaire.
 
Moralité : au lieu de critiquer les réponses des autres intervenants, se concentrer sur la validité de sa propre réponse.

Reply

Marsh Posté le 13-04-2011 à 11:27:06    

Non mais je crois qu'on s'est mal compris:
- Il faut échapper les inputs quand on utilise query()
- Il ne faut pas échapper les inputs quand on utilise prepare() (par exemple en utilisant les marqueurs)
- En règle générale (et surtout pour les débutants): Utiliser prepare() et non pas query().
 
Voilà, donc aucune contradiction dans la doc :bounce:


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 13-04-2011 à 19:17:45    

Pour prépare() faut faire gaffe à bien préciser le type de données avec PDO::PARAM_INT ou PDO::PARAM_STR. J'en vois beaucoup qui ne le font pas.

Message cité 2 fois
Message édité par Profil supprimé le 13-04-2011 à 19:17:54
Reply

Marsh Posté le 13-04-2011 à 19:25:02    

Merci à tous pour vos réponses. Comme je débute , j'ai donc tout intérêt à utiliser "prepare" et pas "query". Et donc je ne m'embête pas à faire des mysql_real_escape_string.
 
Dominique

Reply

Marsh Posté le 13-04-2011 à 20:28:57    


 
C'est comme les gens qui font des trucs genre "select * from blabla where id="1"" alors que "id" est un int.


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 13-04-2011 à 20:41:29    

Par contre esox_ch corrige moi si je me trompe, mais dans mon cas j'utilise la méthode query() uniquement si je n'ai pas de variable dans ma requête à faire passer en paramètre. Donc dans 90% des cas j'utilise prepare(). Je sais pas si c'est judicieux en terme de ressources utilisés par la requête mais comme je me suis toujours mélangé les pédales avec les mysql_escape_trucmuche, les htmlspecialchar etc...

Reply

Marsh Posté le 13-04-2011 à 20:41:29   

Reply

Marsh Posté le 14-04-2011 à 00:24:34    

Bein tu fais comme tu veux [:spamafote]
En général la différence entre une simple "query" et une requête préparée n'a rien à voir avec le fait d'avoir des paramètres échappés ou non.
Une requête préparée prendra en vraisemblablement un peu plus de temps la première fois car elle sera justement "préparée" par le SGBD, mais elle sera considérée comme connue et optimisée par la suite ce qui la rendra plus rapide. Pour une simple query, ce n'est pas le cas.

 

Maintenant il y a plein de mécanismes qui peuvent venir se caler entre deux au niveau des différents caches applicatifs et pour les détails je laisse la parole à qqn qui les a étudiés en détail dans le cadre de PDO couplé à MySQL.

 

Par contre, je pense que toute personne se posant la question "Dois-je utiliser une requête préparée avec prepare()" est directement un bon candidat. En effet pour de petits sites (genre 99% de ceux qu'on voit passer ici), on aura aucune différence de performance notable entre l'un et l'autre. Alors tant qu'à faire, vaut mieux utiliser la solution qui protège contre les injections automatiquement...


Message édité par esox_ch le 14-04-2011 à 00:30:32

---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 18-04-2011 à 14:00:01    


 
Si le mec caste pas les variables qu'il passe en paramètre à sa requête, on peut rien pour lui  :D  
 
Perso, je n'utilise que des ? comme marqueur de paramètre  :)  
 

Code :
  1. SELECT `name` FROM `membre` `M` WHERE `M`.`id` = ?


 
Le problème avec un test PDO::PARAM_INT et consors, c'est qu'il n'y a pas pas d'équivalent flottant.
PDO::PARAM_FLOAT n'existe pas... c'est un peu génant tout de même ! :whistle:


Message édité par CyberDenix le 18-04-2011 à 14:07:27
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed