PHP 6 : Vérifiez la sécurité de vos scripts

Salut tout le monde,

Comme nous vous le disions dans nos derniers billets, PHP 6 va mettre fin à pas mal de choses qui, jusqu’à présent, pouvait simplifier considérablement la vie (soit par ignorance soit par fainéantise). La suppression des magic_quotes va ravir les professionnels du métier, mais faire sans aucun doute grincer les dents de bon nombre d’amateurs qui ne se souciaient pas de la sécurisation de leur site.

Les magic quotes ou les « guillemets magiques » si on veut franciser l’expression permettaient de rajouter des slashes ( \ ) aux apostrophes ( ‘ ) et guillemets (  » ). Cela avait pour but de sécuriser les codes non protégés face aux injections SQL notamment. Une injection SQL, c’est un code qui est détourné dans le but d’obtenir un résultat que l’on ne devrait pas avoir si le script avait été suffisamment sécurisé.

Par exemple, prenons le cas d’un formulaire de connexion, où on demande un pseudo et un mot de passe pour s’identifier. Nous avons un compte avec comme pseudo « toto » et mot de passe « zorro ». La requête va être exécutée de la manière suivante :
SELECT * FROM table_membres WHERE pseudo='toto' AND motdepasse='zorro'

Vous allez me dire : oui et alors ? Eh bien, nous arrivons maintenant au cœur du problème. Imaginons que vous avez quelqu’un qui veut prendre possession de votre compte. Il connait votre pseudo mais ignore bien sur votre mot de passe. Celui-ci va pourtant pouvoir se connecter à votre compte :
SELECT * FROM table_membres WHERE pseudo='toto' AND motdepasse='' OR 'a'='a'

Vous voyez peut-être que la requête est totalement différente. En effet, au lieu d’envoyer le bon mot de passe (ou un faux mais qui serait inoffensif), nous avons là quelqu’un qui essaie une injection SQL. En effet, ce qui est envoyé par le formulaire pour désigner le mot de passe est : ‘ OR ‘1’=’1′
La requête est donc détournée : que le mot de passe soit bon ou pas, vous serez toujours connecté car 1 est toujours égal à 1 !!

Vous imaginez donc le carnage que cela pourrait être ? :) Car la requête donnée précédemment (‘ OR ‘1’=’1′) n’était pas forcément la pire, certains n’hésiteront pas à faire pire en envoyant une requête qui pourrait supprimer totalement votre table de données.

Avec magic_quotes, la requête aurait été différente :
SELECT * FROM table_membres WHERE pseudo='toto' AND motdepasse='\' OR \'a\'=\'a'

Vous le voyez, tous les apostrophes envoyés sont échappés par le caractère \. Et du coup, l’injection SQL ne fonctionne pas. Mais magic_quotes est obsolète depuis PHP 5.3. Il vous faut donc, pour sécuriser vos scripts, utiliser des fonctions PHP toutes simples. Ainsi, au lieu de mettre directement $_POST[‘variable’]; dans votre script PHP, vous mettrez mysql_real_escape_string($_POST['variable']);

Pour les chaînes de type entier numérique, la fonction intval devra être utilisée. Il est donc recommandé de créer votre propre fonction pour gérer ces deux types de cas.

Vos scripts seront ainsi protégés contre les injections SQL qui sont les attaques les plus fréquentes en PHP. Nous en avons terminé sur ce petit articles des injections SQL et nous finirons dans quelques jours ce sujet sur PHP 6 avec d’autres éléments. D’ici là, bon courage et ne paniquez pas car PHP 6 n’est pas encore prêt d’arriver… mais c’est toujours mieux d’avoir un train d’avance comme on dit. ;)

NB : Les explications données dans ce billet valent aussi pour $_GET, les autres superglobales et plus généralement toutes les variables qui nécessitent d’être protégées. Vous devrez donc sécuriser ces variables là de la même manière que précédemment.

Les commentaires sont fermés pour cet article.