Eviter les injections SQL Les variables MySQL pour renforcer la sécurité

MySQL propose un système de variables serveur, qui peuvent être bien pratique pour renforcer la sécurité. Une variable MySQL est créée puis utilisée comme ceci :

mysql> SELECT @login := 'valeur', @passe := 'passe' ;mysql> SELECT count(*) FROM utilisateurs WHERE login = @login AND passe = @passe;


La première requête SQL est une affectation de variables. Ces valeurs sont ensuite réutilisées dans la requête d'identification. Notez qu'on est passé de une à deux requêtes pour réaliser la même fonction. Toutefois, la première requête est très rapide, car il n'y a pas de table impliquée. C'est une simple allocation de mémoire, qui prend un temps insignifiant.

La requête d'identification est désormais protégée, car une valeur introduite dans @login et @passe est maintenant traitée comme une valeur et non plus comme une partie de la commande. MySQL sait parfaitement faire la différence entre les valeurs et la commande : il n'y a plus de danger d'injection.

En réalité, vous aurez remarqué que le problème a simplement été déplacé. Au lieu de faire une injection dans la requête d'identification, elle peut désormais avoir lieu dans la requête d'allocation des variables.

Toutefois, il devient maintenant très facile de protéger l'affectation des variables : c'est toujours la même requête qui effectue l'affectation. Sa structure est simple et facile à protéger avec des guillemets et des fonctions de protection. Il n'y a plus à protéger différents types de commandes tels SELECT, UPDATE, INSERT, CREATE, DROP, SET, etc.

De plus, l'impact d'une injection est considérablement réduit, puisque l'injection se passe désormais lors de l'affectation de la variable et non plus dans la commande utile. Dans le cas où une vulnérabilité inconnue serait exploitée, c'est la commande SET qui serait affectée et non plus la manipulation directe des données, utilisant SELECT, UPDATE ou DELETE.

Notez que la commande SELECT de MySQL retourne la valeur qui a été affectée par la requête. Cela permet de recevoir la valeur qui a été envoyée en même temps que l'affectation.

 mysql> SELECT @passe := '' or (1) = '1';
+---------------------------+
| @passe := '' or (1) = '1' |
+---------------------------+
| 1 |
+---------------------------+
1 row in set (0.00 sec)


Cette technique est souvent méconnue, mais elle a le mérite d'être simple à appliquer et de bien séparer les commandes et les valeurs, comme le font les commandes préparées. Elle rend aussi les requêtes SQL complètement fixes et plus lisibles dans le code : plus besoin de construire des requêtes SQL complexes à la volée, mais simplement des affectations de variables et des requêtes fixes.