[Php] – Comment gérer correctement les magic-quotes.

Les magics-quotes sont un ensemble d’options en PHP, options qui gèrent les chaînes de caractères.

Leurs utilisation devient hasardeuse en cas de mauvaise compréhension du rôle de chacune de ces options.

Nous allons essayer au cours de cette article d’y voir clair dans le jeu de PHP.

1°) 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 »;
?>

2°) 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 »
?>

Mais quel est le but et la raison de ces options:

Le problème des ‘injections SQL’.
Les injections SQL, qui représente une faille de sécurité, offre 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.