Le point sur les magic_quotes
Les magic_quotes sont des fonctionnalités de php qui apportent des facilités dans le traitement des chaines de caractères. Une mauvaise compréhension de leur fonctionnement conduit à des comportements inadaptés voir même dangereux ...
Description des magic_quotes
- magic_quotes_runtime
L’activation de cette option provoque automatiquement l’échappement des caractères spéciaux des chaines issues des fichiers ou des bases de données
<?php // le fichier contient la chaîne "I’m the king of the world"
$fp = fopen(’url’,’r’) ; $file = fread(’$fp,128) ;
// magic_quote_runtime sur off echo $file ; // renverra "I’m the king of the world"
// magic_quote_runtime sur on echo $file ; // renvera "I\’m the king of the world" ;
- magic_quotes_gpc
L’activation de cette option provoque automatiquement l’échappement des caractères spéciaux des chaines issues de get, post ou cookie.
<?php
// Vous venez de remplir un formulaire avec un champ nommé ’RoiDuMonde’ qui // contient "I’m the king of the world"
// magic_quote_gpc sur off echo $_POST[’RoiDuMonde’] ; // renverra "I’m the king of the world"
// magic_quote_gpc sur on echo $_POST[’RoiDuMonde’] ; // renverra "I’m the king of the world"
?>
Pourquoi faut il échapper les caractères spéciaux ?
La meilleure réponse à cette question, c’est de parler du problème des injections SQL :
Dans un soft, on trouve cette portion de code pour tester la validité d’un mot de passe :
<?php
// requête SQL typique d’une interface utilisateur $sql = "SELECT login,password FROM user_tbl WHERE login = ’".$login."’ AND password = ’".$password."’ ;
?>
Apparemment, tout va bien. Par exemple si tout va bien on pourrait avoir la séquence suivante :
<?php
$login = ’fabrice’ ; $password = ’jigoro’ ;
?>
Ce qui donnerait la requête :
SELECT * FROM user_tbl WHERE login = ’fabrice’ AND password = ’jigoro’
Tout va toujours bien.
Par contre, si l’utilisateur est taquin et qu’il fournit le mot de passe un peu particulier : ’ OR password LIKE ’% :
<?php
$login = ’fabrice’ ; $password = "’ OR password LIKE ’%" ;
?>
La requête devient :
SELECT * FROM user_tbl WHERE login = ’fabrice’ AND password = ’’ OR password LIKE ’%’
Et voila ... La requête fournit un résultat, alors qu’on a pas founi le bon mot de passe ....
Si les quotes avaient été echappées, ce cas de figure n’aurait pas pu se produire
Utilisation des magic_quotes
De l’exemple précédent, on déduit qu’il est bon d’échapper toutes les chaines de caractères en entrée de base. C’est ce qu’il se passe automatiquement pour les chaînes issues de l’extérieur si les magic_quotes sont à on. Mais là, un autre casse tête commence : il faut traiter séparément les chaînes qui proviennent de l’extérieur et celles qui proviennent de l’intérieur. Et puis il faut traiter les affichages pour supprimer les slashes inopportuns. Sans compter que les slashes peuvent générer des erreurs en rallongeant artificiellement la longueur des chaînes.
Bon, ben alors ? On fait comment ?
En fait, la bonne solution, c’est de désactiver les magic_quotes et de gérer à la main l’ajout des slashes lors des insertions SQL (la fonction addslashes est faite pour ça).
Comment on désactive les magic_quotes ?
Là encore, ça n’est pas simple ! La méthode de base, c’est de les mettre à off dans le php.ini :
; Magic quotes for incoming GET/POST/Cookie data. magic_quotes_gpc = Off
; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc. magic_quotes_runtime = Off
Mais dans le cas d’un hébergement mutualisé, on a pas accès au php.ini. Toutefois, certains hébergeurs permettent de les modifier via le fichier .htacces et la directive php_flag :
php_flag magic_quotes_gpc off php_flag magic_quotes_runtime off
Là encore, cette solution n’est pas toujours possible. il va falloir ...
... Désactiver les magic_quotes via php
Pour les magic_quotes_runtime, c’est facile, il y a une fonction (set_magic_quotes_runtime) qui fait ça :
<?php set_magic_quotes_runtime(0) ; ?>
Par contre pour les magic_quotes_gpc, il faut le coder, la fonction n’existe pas ...
Il faut donc inclure le script suivant avant toute action d’entrée sortie :
<?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) ;
?>
Et voila ! Maintenant, il ne reste plus qu’a ne pas oublier d’échapper toutes les chaînes dans les requêtes SQL.
Cette solution présente en outre l’avantage d’être indépendante des conditions d’hébergement ...
Réalisation de sites web

