Un advisory de Janvier 2005 qui faisait parti de quelques centaines de problèmes similaires à l'époque sur une application PHP provient du fait que celle-ci ne valide pas les paramètres d'une requête en base de données, ce qui pourrait permettre à un pirate d'effectuer des injections SQL. La chose étrange par rapport à cet advisory sur PHP Gift Registry, c'est que 8 ans plus tard, les développeurs ont décidé de réagir.
Le message annonçant cette correction du 3 Décembre 2012 vient du développeur et dit : "Toutes les requêtes SQL ont été remplacées par des déclarations paramétrées dans la version 2.0.0".
Ces types de vulnérabilités par injection SQL sont encore très répandues et sont en général les failles les plus importantes sur une application Web. Les prepared statements ou "instructions préparées" si vous préférez, sont un des moyen les plus faciles et les plus efficaces pour se prémunir de ce genre de faille.
Dans le cas qui suit, le développeur prépare sa requête et déclare la variable qui doit être spécifiée plus tard.
$stmt = $dbh->prepare("SELECT user FROM users WHERE (user=:user)"); $stmt->bindParam(':user', $user);
Quand le script est exécuté, le développeur n'a plus qu'à spécifier le nom d'utilisateur et exécuter la requête en base de données :
$user = 'lama'; $stmt->execute();
L'avantage de cette méthode est que, même si, pour une raison x/y, quelque chose comme :
lama';DROP TABLE users; --
se retrouve dans la variable $user, il sera toujours traité comme un critère de recherche et ne conduira pas à la suppression d'une table comme ici.
Si vous pensez à la fonction mysql_real_escape_string() en PHP qui réagit à peu prés de la même façon, elle n'est pas conseillée à moins que vous définissiez correctement le jeu de caractère soit au niveau serveur, soit avec la fonction API mysql_set_charset().