Ceci est une ancienne révision du document !
Pour dynamiser un site on est très souvent amené à utiliser des bases de données afin de stocker des informations. Par exemple, un site d'information stockera ses news dans sa base de donnée. Pour parler avec cette base de données le développeur va utiliser un langage spécial : le SQL.
-- Exemple d'une requête simple SELECT titre,auteur,contenu FROM news WHERE id = 1337
Maintenant, imaginons que chaque news est chargé dynamiquement à partir d'un paramètre de l'URL
<?php mysql_connect("localhost","root","root"); mysql_select_db("sqli"); $news = mysql_query("SELECT titre,auteur,contenu FROM news WHERE id = ".$_GET['id']); $news = mysql_fetch_assoc($news); echo "<h1>".$news['titre']."</h1> par <i>".$news['auteur']."</i><br/>"; echo "<p>".$news['contenu']."</p>";
La sélection de la news se fait en fonction de la variable GET id. Par exemple, news.php?id=1 affichera la première news, et ainsi de suite …
Le soucis dans ce code c'est que la variable GET est utilisée directement dans la requête SQL. Le client malveillant contrôle parfaitement cette variable et peu donc à tout moment modifier le comportement de la requête afin de sélectionner ce que bon lui semble dans la base de donnée. C'est le principe de l'injection SQL.
On va étudier le cas d'une page qui affiche des news stockées dans une base de donnée. Notre but va être de récupérer le mot de passe de l'administrateur qui est stocké dans la base de donnée. Afin que vous puissiez reproduire ce scénario chez vous, si vous le souhaitez, voici les différentes requêtes pour créer les tables ainsi que le script PHP.
-- -- Structure de la table `news` -- CREATE TABLE `news` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `titre` VARCHAR(255) NOT NULL, `auteur` VARCHAR(255) NOT NULL, `contenu` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; -- -- Contenu de la table `news` -- INSERT INTO `news` VALUES(1, 'Première news', 'tlk', 'Contenu première news'); INSERT INTO `news` VALUES(2, 'Seconde news', 'tlk', 'Contenu seconde news'); -- -------------------------------------------------------- -- -- Structure de la table `users` -- CREATE TABLE `users` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `password` VARCHAR(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; -- -- Contenu de la table `users` -- INSERT INTO `users` VALUES(1, 'administrateur', 'SuperPass');
<?php mysql_connect("localhost","root","root"); mysql_select_db("sqli"); $news = mysql_query("SELECT titre,auteur,contenu FROM news WHERE id = ".$_GET['id']); $news = mysql_fetch_assoc($news); echo "<h1>".$news['titre']."</h1> par <i>".$news['auteur']."</i><br/>"; echo "<p>".$news['contenu']."</p>";