[French] Protection contre le SQL Injection

EDB-ID:

12873

CVE:

N/A


Author:

Moudi

Type:

papers


Platform:

Multiple

Date:

2009-09-03


/*

              _____       _ ___        __          
             | ____|_   _(_) \ \      / /_ _ _   _ 
             |  _| \ \ / / | |\ \ /\ / / _` | | | |
             | |___ \ V /| | | \ V  V / (_| | |_| |
             |_____| \_/ |_|_|  \_/\_/ \__,_|\__, |
                                              |___/ 
                                    _____                    
                                   |_   _|__  __ _ _ __ ___  
                                      | |/ _ \/ _` | '_ ` _ \ 
                                      | |  __/ (_| | | | | | |
                                      |_|\___|\__,_|_| |_| |_|

[french] Protection contre le SQL Injection

Tutorial par : Moudi
Contact : <m0udi@9.cn>
English ( Avoiding SQL Injection ) : http://milw0rm.com/papers/358

Greetings : Mizoz, Zuka, str0ke, 599eme Man.
Please visit: http://unkn0wn.ws/board/index.php

*/

--------------------------------------------------------------------
	
Les SQL Injection sont parmi les failles les plus répandus et dangereux en PHP.
Ce tutorial va expliquer clairement le concept de SQL Injection et comment les éviter, une fois pour toutes.

>>>>>> >>>>>>
Résumé de tutorial:
   I) Présentation du problème.
      => Les variables contenant des chaînes
   Ii) la sécurité.
      => Explication
      => Les variables numériques
         . Méthode 1
         . Méthode 2
>>>>>> >>>>>> 

--------------------------------------------------------------------


I) Présentation du problème.
    ___________________________

Il existe deux types d'injection SQL:

* L'injection dans les variables qui contiennent des chaînes;
* L'injection dans les variables numériques.

Ce sont deux types très différents et a éviter, il agira
différemment pour chacun de ces types.

######################
Les variables qui contiennent des chaînes:
######################

Imaginez un script PHP qui récupère l'âge d'un membre conformément à son
surnom. Ce surnom est parti d'une page à l'autre via l'URL
(en $ _GET quoi: p). Ce script devrait ressembler à ceci:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
...
$ pseudo = $ _GET [ 'pseudo'];
$ requete = mysql_query ( "SELECT age FROM membres WHERE pseudo = '$ pseudo'");
...
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++


Eh bien tenez vous bien, ce script est une grande vulnérabilité par injection SQL.
Il suffit d'un mauvais garçon en mettant en place le nom d'utilisateur dans l'URL d'une requête
comme ceci:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
'Password UNION SELECT FROM membres WHERE id = 1
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++


Il est d'arriver à montrer (juste un exemple), par exemple le mot de passe
le membre ayant l'ID 1. Je ne vais pas expliquer en détail le fonctionnement de
la peur que quelqu'un n'est pas agréable pour s'y promener. Eh bien, laissez-nous donc aller à la
la sécurité:).

Ii) la sécurité.
_______________

Pour sécuriser ce type d'injection est simple. Vous utilisez la fonction
mysql_real_escape_string ().

######################
Euh ... Elle fait ce que c'est?
######################

Cette fonction ajoute le caractère "\" pour les caractères suivants:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
NULL, \ x00, \ n, \ r, \, ', "et \ X1A
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

######################
And what's the point?
######################

Comme vous l'avez remarqué dans l'injection précédente, l'attaquant utilise la citation
(pour fermer la 'Around $ nick): si elle est empêchée de le faire, l'
bad boy n'auront qu'Ã  aller voir ailleurs. Cela signifie que si l'on
applique un mysql_real_escape_string () pour le nom de variable comme ça ...

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
...
$ pseudo = mysql_real_escape_string ($ _GET [ 'pseudo']);
$ requete = mysql_query ( "SELECT age FROM membres WHERE pseudo = '$ pseudo'");
...
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

L'application est entièrement sécurisé.
Explication

######################
Hacker par injection d'un rappel:
######################

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
'Password UNION SELECT FROM membres WHERE id = 1
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

Eh bien, si nous appliquons mysql_real_escape_string () à la variable $ nom utilisé
dans la requête est ce qui va de l'injection:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
\ 'Union de passe Sélectionnez membres WHERE id = 1
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

Cela signifie que nous ne viennent pas même en dehors des quotes autour de $ nick dans
la requête car la \ a été ajoutée. Il existe une autre fonction
quelque peu semblable à mysql_real_escape_string () est addslashes (), pourquoi
ne pas avoir utilisé? Eh bien récemment, une faille de sécurité a été découvert à ce sujet si
Il est utilisé sur une installation de PHP 4.3.9 avec magic_quotes_gpc est activé.

######################
Variables numériques:
######################

Ce type d'injection est moins connue que la précédente, ce qui en fait
plus fréquentes, et il commence comme tout à l'heure avec un exemple. Cette fois, c'est
affichage de l'âge d'un membre en fonction de son id, et en le faisant passer par un
formulaire ($ _POST) Ã  changer:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
...
$ id = $ _POST [ 'id'];
$ requete = mysql_query ( "SELECT age FROM membres WHERE id = $ id");
...
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++


mysql_real_escape_string () serait rien ici, car si un attaquant
veut injecter du code SQL, il n'aura pas besoin d'utiliser des guillemets, parce que le
variable $ id n'est pas entouré de guillemets. Simple exemple d'une
exploitation:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
2 UNION DE passe Sélectionnez membres WHERE id = 1
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

Cette injection a fait exactement la même que la précédente, sauf que
ici, pour l'éviter, il ya deux solutions:

      * Changer le contenu de la variable si elle contient uniquement des chiffres;
      * Vérifiez si la variable contient en réalité un certain nombre avant de l'utiliser dans une requête.

##########
Méthode 1:
##########

Nous allons utiliser une fonction intval () Cette fonction retourne quel que soit le
contenu d'une variable sa valeur numérique. Par exemple:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
e10 variable = '1 '; / / $ variable vaut '1 e10'
valeur_numerique $ = intval ($ variable); / / $ vaut valeur_numerique 1
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

Maintenant, revenons à nos moutons:

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
$ id = intval ($ _POST [ 'id']);
$ requete = mysql_query ( "SELECT age FROM membres WHERE id = $ id");
)
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

Cela signifie que vous pouvez y passer et est plus que suffisante, mais je vous recommande
continuer à trouver une autre méthode, ou si vous avez l'air bête si vous trouvez cette
méthode sur un code qui n'est pas le vôtre sans le comprendre.

############
Méthode 2:
###########

Ici, nous utilisons une fonction qui renvoie TRUE si une variable ne contient que
nombres et FALSE si elle n'est pas le cas cette fonction is_numeric (),
nous allons l'utiliser dans une condition qui vérifie si la fonction is_numeric () retourne
TRUE bien.

++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++
$ id = $ _POST [ 'id'];
if (is_numeric ($ id))
(
$ requete = mysql_query ( "SELECT age FROM membres WHERE id = $ id");
)
autre
(
echo "Essayer de me hack? MOTHA FUCKAH xD";
++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++

################################################## ################
Quel est le meilleur, en fonction intval () et is_numeric ()?
################################################## ################

Eh bien je dirai que les deux sont tout aussi efficaces, ils sont égaux.
Mais je préfère inval () car avec la fonction is_numeric () écrire plus de code, et si
la variable ne contient pas seulement des chiffres, la demande est annulée (en
principe, mais bien sûr vous pouvez exécuter la même requête en choisissant une
Valeur par défaut de la variable utilisée). Well that's it! Vous savez tout
sécuriser vos applications. Si vous appliquez ces méthodes, il ya
absolument aucun risque d'avoir un type de faille d'injection SQL sur son site web
(ou PHP). 

# milw0rm.com [2009-09-03]