Mardi 12 Août 2003
[Php] - Comment gérer correctement les magic-quotes.
Introduction.
Les magics-quotes sont un ensemble de trois options de PHP accessible via le php.ini et qui gère les chaînes de caractères. Mais leurs utilisation devient complètement anarchique et même dangereuse quand l'on ne sait pas s'en servir.
Présentation des options.
L'option magic_quotes_runtime permet, si elle est activée, d'échapper tous les caractères spéciaux des chaînes provenant de fichiers ou de base de données
Exemple :
<?php
// le fichier contient la chaîne "aujourd'hui"
$fp = fopen('url','r') ;
$file = fread('$fp,128);
// magic_quote_runtime sur off
echo $file; // renverra "aujourd'hui"
// magic_quote_runtime sur on
echo $file; // renvera "aujourd\'hui";
?>
L'option magic_quotes_gpc permet, si elle est activée, d'échapper tous les caractères spéciaux des chaînes provenant de Get, Post ou Cookie.
Exemple :
<?php // Vous venez de remplir un formulaire avec un champs nommé 'champs' qui contient "aujourd'hui" // magic_quote_gpc sur off echo $_POST['champs']; // renverra "aujourd'hui" // magic_quote_gpc sur on echo $_POST['champs']; // renverra "aujourd\'hui" ?>
Le problème des 'injections SQL'.
Les injections SQL c'est la possibilité d'exécutée une requête SQL différente de celle prévu par le programmeur.
Exemple :
<?php // requête SQL typique d'une interface utilisateur $sql = "SELECT * FROM user_tbl WHERE login = '".$login."' AND password = '".$password."'; ?>
Note : Le SELECT * n'est pas recommandé. Et pour une sécurité optimale, l'on optera pour un password crypté en MD5.
Cette requête semble inoffensif en utilisation normale :
<?php $login = 'guillaume'; $password = 'sauce_tomate'; ?>
La requête est donc SELECT * FROM user_tbl WHERE login = 'guillaume' AND password = 'sauce_tomate'
Maintenant, modifions un peut nos valeurs :
<?php $login = 'guillaume'; $password = "' OR password LIKE '%"; ?>
La requête est donc SELECT * FROM user_tbl WHERE login = 'guillaume' AND password = '' OR password LIKE '%' et la ligne est quand même sélectionnée alors que le password n'est pas correct.
Tout ceci aurait pu être évité si les quotes (') avaient été échappées.
Utilisation des magic_quotes.
Nous avons donc vu que il était nécessaire d'échapper toutes chaînes de caractères en entrée de base de données et que les magic_quotes le font gentiment pour nous quand elles sont à on. Mais cela pose quand même des problèmes.
En premier lieu, les chaînes générés par PHP et qui ne viennent pas de l'extérieur (base, fichier, formulaire) ne sont pas échappées et il peut devenir anarchique de savoir si une chaîne vient de l'extérieur ou de l'intérieur. De plus, les affichages doivent tous être nettoyé et cela devient rébarbatif. Pour finir, les slashes peuvent fausser les traitements car ils allongent les chaînes.
En conclusion, il est plus simple de désactivé les magic_quotes et de penser à ajouter soit même les slashes lors d'une requête SQL via la fonction addslashes().
Réglages des magic_quotes.
La technique la plus simple est de modifié directement dans le php.ini en mettant les valeurs de magic_quotes_gpc et magic_quote_runtime à off, mais il est rare d'avoir accès au php.ini.
Le seconde solution et d'utilisé Apache et les fichier .htaccess et la directive php_flag.
php_flag magic_quotes_gpc off php_flag magic_quotes_runtime off
Mais encore, certains hébergements n'autorisent pas cette utilisation, il va donc falloir faire autrement.
Réglages via php.
Pour les magic_quotes_runtime, cela n'est pas extrêmement dur via la fonction set_magic_quotes_runtime().
<?php set_magic_quotes_runtime(0); ?>
En ce qui concerne magic_quotes_gpc, cela se complique car il n'y a pas de fonction pour faire cela 'à la volée', il va donc falloir faire une boucle se chargeant de nettoyer les variables.
Les variables concernées sont $_POST, $_COOKIE, $_GET, $_REQUEST, $_SERVER, $_FILES.
<?php
# On n'exécute la boucle que si nécessaire
if(get_magic_quotes_gpc() == 1){
# Définition de la fonction récursive.
function remove_magic_quotes(&$array)
{
foreach($array as $key => $val){
# Si c'est un array, recurssion de la fonction, sinon suppression des slashes
if(is_array($val)){
remove_magic_quotes($array[$key]);
} else if(is_string($val)){
$array[$key] = stripslashes($val);
}
}
}
# Appel de la fonction pour chaque variables.
# Notes, vous pouvez enlevez celle d'on vous ne vous servez pas.
# Personnellement, j'enlève $_REQUEST et $_FILES
remove_magic_quotes($_POST);
remove_magic_quotes($_GET);
remove_magic_quotes($_REQUEST);
remove_magic_quotes($_SERVER);
remove_magic_quotes($_FILES);
remove_magic_quotes($_COOKIE);
}
?>
Ce script est à appeler avant tout autre action, via la fonction require().
Conclusion.
Maintenant, vous ne devez pas oublié d'échapper toutes les chaînes dans les requêtes SQL , mais c'est la seul chose à laquelle vous devrez penser, le script se charge du reste. L'autre avantage c'est que si jamais votre hébergement change de réglages, vous êtes compatible, c'est ce que l'on appel la portabilitée.
Commentaires
Mardi 21 Octobre 2003 11:53:33 - l'homme
pas mal!
Vendredi 23 Janvier 2004 10:43:02 - éma
l'entreprot l'église de fête
Vendredi 14 Mai 2004 22:07:38 - YoGi Lien
Tu peux aussi utiliser une directive dans ton .htaccess (si tu utilises apache oeuf course) pour désactiver les magic_quotes_gpc, pour peu que ton host l'autorise, c'est plus pratique :)
php_flag magic_quotes_gpc off
Samedi 15 Mai 2004 14:04:18 - Guillaume
J'en parle pas dans l'article ?
Samedi 22 Mai 2004 02:03:05 - ken Lien
c'est vraiq ue ca aide pas mal moi qui ai tjs les mm probleme ...
Lundi 21 Février 2005 16:12:59 - sam Lien
rien compris...
Lundi 04 Avril 2005 11:07:18 - ge
g deja vu ce tuto... ;)
Mercredi 20 Avril 2005 13:04:06 - terrien
Salut
bonne synthese du problème. j'en étais arrivé au même résultat sans le formuler et le présenter ainsi et bon pour en prendre conscience.
un petit point :
En conclusion, il est plus simple de désactivé les magic_quotes et de penser à ajouter soit même les slashes lors d'une requête SQL via la fonction addslashes().
personnellement et même si ça ne change pas grand chose je pousse pour que soient utilisées les fonction spécifique du moteur de base de donéee utilisé.
mysql_escape_string
pg_escape_bytea
pg_escape_string
etc.
merci tout de même
A+
Mardi 07 Mars 2006 23:47:12 - vodkapom Lien
vraiment intéressant, net et précis ;)
Mardi 04 Avril 2006 06:01:31 - Ludo
Pas mal ce rose
Mercredi 05 Avril 2006 00:35:39 - Fvr
Merci pour ce récapitulatif synthétique et clair. J'étais en train d'arriver à la même conclusion mais ça m'a permis de confirmer ma pensée.
Mercredi 27 Septembre 2006 10:10:13 - azertyh
Salut,
Cela fait peut-être 1 heure que j'essai de comprendre ça:
citation :
En conclusion, il est plus simple de désactivé les magic_quotes et de penser à ajouter soit même les slashes lors d'une requête SQL via la fonction addslashes().
fin de citation
Franchement ça explique mal ce que tu veux dire. Mais enfin, exprimez vous completement, afin de bien vous faire comprendre bordel de merde !!!!!!!!!!
Réagissez
En fait non ! Trop de smap