Salagir's Blog

Old name was: "Why do witches burn?"

This is french section. Go to English version

PHP garde jusqu’à sa version 5 un paramètre de sécurité activé par défaut qui m’insupporte, c’est le Magic Quote.
Quand ce flag est à On, alors les variables qui sont dans les cookies, et passé par formulaire ou url d’une page à l’autre, sont automatiquement « escapés » (du mot anglais escape).
Cela veut dire que des anti-slashs sont ajoutés avant certains caractères particuliers. L’apostrophe (simple quote) particulièrement.

Exemple : mon script toto.php contient le code : Bonjour <?= $_GET[‘nom’] ?> !.
On appelle : toto.php?nom=Bob ; ça affiche Bonjour Bob !
On appelle : toto.php?nom=Muad’ib ; ça affiche Bonjour Muad\’ib !

Pourquoi ? Parce que quand le développeur est en fait un bidouilleur, il peut appeler ensuite une requete SQL utilisant cette donnée (donc totalement modifiable par l’utilisateur) et s’il oublie de mettre des \ là où il faut, c’est un trou de sécurité, on peut faire une SQL injection.

Exemple : toto.php affiche des données d’un compte de gars sur un site. Le gars ne voit que ses propres données.

$nom = $_GET['nom'];
$id = id_du_gars_que_comme_ca_on_lit_que_des_donnes_a_lui();
echo $SQL-&gt;query2cell("SELECT valeur FROM donnees_gars WHERE id_gars=$id AND clef='$nom'");

Que ce passe-il maintenant si on appelle avec une valeur de nom à la con ? Du genre coincoin’ OR ‘a’=’a
Et bien vous l’avez compris : cela annule totalement la vérification de l’id du gars.
Pour si vous n’avez pas compris, la condition à vérifier sera (id_gars=$id AND clef=’coincoin’) OR (‘a’=’a’) et la partie droite est toujours vrai.

Si le développeur a pensé utiliser $nom = addslashes($_GET[‘nom’]) ou que magic quote est activé, alors la condition de recherche sera id_gars=$id AND clef=’coincoin\’ OR \’a\’=\’a’ et on cherchera bien une clef qui a ce nom à la con.

Bon j’arrête le cours, voici mon script.

Parce que moi je suis un vrai dev et j’en ai plus que marre de ce magic quote… A chaque fois que je bosse sur un script, je dois prendre en compte ce paramètre, et il m’arrive bien souvent d’utiliser le code suivant :

if (get_magic_quotes_gpc()) $_POST = array_map('kill_magic_quotes', $_POST);
function kill_magic_quotes($v) {
	return is_array($v) ? array_map('kill_magic_quotes', $v) : stripslashes($v);
}

Mais maintenant je désactive tout simplement ce flag et j’utilise du code bien propre.
Sauf que ! Il arrive, en passant le code d’une machine à l’autre, que j’oublie cela, et quelques données en base de données se retrouvent alors corrompues et pleines de ‘ ….

J’ai donc écris un script à utiliser en ligne de commande, nommé simplement « del slash » (oui « del anti slash » était trop long). Il prends en paramètre un nom de table et un nom de champs, et gère tout le reste.
Il fait de belles vérifications d’erreurs, donc il est cool et pratique. Voilà.

EDIT: upgrade du script, il accepte maintenant les tables avec plusieurs clefs primaires.

Vous pouvez télécharger le code ici :

Le script en ligne de commande se lance de la façon suivante :

php del_slashs.php nomtable nomchamps

Mettez le fichier sqlQueries.php dans le même dossier, et éditez del_slash.php pour y mettre vos paramètres de connexion à la base de donnée.

2 Responses to “Détruire les anti-slashs : mort à magic_quotes_gpc”

  1. Bon je sais que tu es un fervent défenseur du PHP4, mais j’ai une bonne nouvelle pour toi…
    En PHP6, magic_quotes_gpc disparait. Seul bémol de taille, c’est que si PHP6 mais autant de temps que PHP5 à être debugger et à s’imposer, on a largement le temps d’utiliser ton code et ça c’est cool :) .

    nyamsprod

  2. Moi ce qui m’insupporte, ce n’est pas les Magic Quotes en soit.

    Leur invention est presque une bénédiction pour les milliers de boulets, rittals, ou gays, qui essayent d’apprendre ce langage. Ca leur évite de faire certains scripts injectables à leur insu (mais ils arrivent quand même).

    Ce qui m’insupporte c’est le fait qu’on puisse les avoir activés ou désactivés, selon le serveur où l’on se trouve. Du coup, les programmeurs se font avoir à chaque changement de ce paramètre, et soient oublient de faire addslashes avant de mettre des données en BDD, soient oublient le stripslashes avant l’affichage. Dans les 2 cas, c’est mal. Ou alors, on s’amuse à vérifier leur présence, et franchement, ce genre de code, on devrait pouvoir s’en passer.

    Il faudrait simplement se décider sur un mode de fonctionnement une fois pour toute, et qui soit le même partout. En cela PHP6 qui vire le paramètre est une bonne nouvelle.

    Antibuzz

Leave a Reply