Vous êtes ici Articles > Se protéger des injections SQL

 

Se protéger des injections SQL

Du coté PHP
 
phpSources
Vu 2207 fois
Enregistré le 11 Déc 2008
  • Digg cet article sur digg.com
  • Bookmark cet article sur del.icio.us
  • Bookmark cet article sur Google
  • Bookmark cet article sur Yahoo
  • Ajoute Se protéger des injections SQL
  • Partage cet article sur Facebook
 
 
 
 

Se protéger des injections SQL


Lors de l'interrogation de votre base de données, évitez que les données douteuses rendent votre application vulnérable aux injections SQL et donc peu fiable. Certains programmeurs pensent qu'ils ont résolu le problème en utilisant des magic_quotes dans leur php.ini. Le problème est que les entrées douteuses peuvent provenir de sources autres que $ _GET, $ _POST et $ _COOKIE (provenant d'autres sites ou utilisant des entrées de la base de données). Et que se passe-t'il si soudainement magic_quotes est réglé sur OFF?

Comment faire pour résoudre ce problème:
Il faut mettre les magic_quotes sur OFF dans le fichier php.ini ou bien utiliser le fichier .htaccess. Ensuite utiliser la fonction mysql_real_escape_string() sur toutes les variables utilisées dans les expressions SQL.


.01
.02
.03
.04
.05
.06
.07
.08
.09
.10
.11
 
<?php

$requete_sql " UPDATE table
                 SET nom = '".mysql_real_escape_string($nom)."'
                 WHERE id = ".mysql_real_escape_string($id)."
               ";

mysql_query($requete_sql);

?>


Si vous laissez les magic_quotes sur ON, vous devrez vous fier à votre instinct.

Commentaires
Bien sûr cette protection n'est pas suffisante car on peut très bien injecter une requête SELECT qui ne contient pas de caractères spéciaux. Par exemple : SELECT BENCHMARK(1000000000000,(MD5(1)) Cette requête va rendre le serveur MySQL complètement inutilisable et pourtant la requête injectée ne contient aucun caractères spécial mysql échappable. Le seul moyen de faire les choses proprement est d'utiliser les requêtes préparées avec MySQLi ou PDO.
 
Ça me rappelle l'excellent strip paru sur XKCD il y a un moment : http://xkcd.com/327/ La première sécurité pour moi est de toujours valider les données injectées dans la base avant même de se poser la question d'échapper les caractères.
 
[cit nom=Unknown]Le seul moyen de faire les choses proprement est d'utiliser les requêtes préparées avec MySQLi ou PDO. [/cit] +1 C'est vraiment le seul moyen (facile). Après il y a toute l'histoire des ORM ([url]http://www.doctrine-project.org/[/url]). Mais un chouille plus compliqué.
 
pour mysqli il faut une version mysql >= mysql 4.1.3 et une version php >= php5 Si l'on regarde les stats de Nexen de Septembre 2008 : par ici il y a + de 50% des serveurs qui sont avec des versions inferieurs à php5
 
Réponse @ Invité du 11 décembre

Pour injecter ton fameux « SELECT BENCHMARK(1000000000000,(MD5(1)) » toujours faut-il le sortir d'entre les 2 apostrophes

le select * from NimporteQuoi where Champ=' SELECT BENCHMARK... ' ne fera pas broncher ton sgbd du tout, il retournera tout simplement aucun résultat. Pour faire tousser ton serveur il faudrait que tu puisses éxécuter ton select benchmark en refermant ton apostrophe genre : select * from Nimportequoi where Champ=' '; SELECT BENCHMARK... ; -- ' mais dans ce cas, ton apostrophe est enlevé, donc aucun danger.
 
Faudra quand même qu'on m'explique comment un "pirate" peu faire passer cette requête SELECT BENCHMARK(1000000000000,(MD5(1)) dans la requête exposée dans l'exemple  UPDATE table
                 SET nom = '".mysql_real_escape_string($nom)."'                  WHERE id = ".mysql_real_escape_string($id)."                ";
Je sais, vive les pirates, mais faut peut-être pas pousser ?


 
Ajouter un commentaire
Code de sécurité

Attention: Les champs marqués d'une étoile * sont obligatoires
 
Quelques articles qui devraient vous intéresser