Injections SQL et méthodes de protection
Auteurs : Rémi Rebillard et Loïc Robergeon
Les injections SQL (ou SQLi pour SQL Injection) est une une faille de sécurité dans les formulaires. On injecte dans une requête SQL, un morceau de requête qui n'est pas prévu par le système et va alors renvoyer des informations qui lui sont normalement caché, voir même les modifier.
Qu'est ce que c'est ?
Le SQL (Structured Query Language) est un langage informatique permettant d'interagir avec différente base de données relationnelles.
Il permet notamment de créer des tables dans cette base de donnée, ainsi que de les modifier.
Il est consitué de requêtes (query) qui vont interagir avec la base de donnée associée afin d'ajouter ou consulter des informations dans celle-ci.
Historique du SQL
Créé en Juin 1970 chez IBM par Donald Chamberlin et Ramond Boyce, ce langage a été conçut pour manipuler des bases de données relationnelle via des requètes.
Au départ, le nom était Structured English QUEry Language (SEQUEL) puis a été changé en SQL a cause d'un conflit de marque déposée.
C'est ensuite en 1979 qu'apparait la première version commercialement disponible de SQL dans le marché.
Il a pas la suite été reconnue comme norme internationale par l'ISO en 1987, et continue d'évoluer régulièrement depuis.
Qu'est ce qu'une injection SQL ?
Les injections SQL s’effectue principalement sur des formulaires dans des pages Web. Ces formulaires demande des informations à l'utilisateurs (login, mot de passe...), qui vont être saisie par l'utilisateur. Cette saisie est alors utilisé dans la requète SQL afin de récupérer les informations désirées par l'utilisateurs. Cette requète SQL interagie directement sur la base de donnée du serveur.
<<Image exemple formulaire>>
Cependant, certains site web sont mal configuré, et des failles apparaisse alors dans ceux-ci. Par exemple, au lieu de rentrer son login dans le précédant formulaire, on rentre d'autres informations comme :
<<Image exemple injection dans un formulaire>>
Ces caractères sont spéciaux car ils vont interagir directement sur la requète SQL lié au formulaire. Au lieu de se servir des informations présentes dans le formulaire, les informations vont modifier la requête et retourner des informations qui ne sont pas accessible a l'utilisateurs.
L'utilisateur va alors pouvoir effectuer diverse actions sur la base de donnée, comme consulter la liste des personnes présente avec leurs informations personnels, ou même la modifier.
Quels sont les différents types d’injection ?
Connexion sans mot de passe :
<<Image exemple injection dans un formulaire sans mot de passe>>
SELECT * FROM Users WHERE name='Alice'; -- 'AND password = 'xxx';
Cette requète signifie qu'on souhaite se connecter avec l'utilisateurs "Alice". Cependant, on tente d'injecter du code SQL afin de pouvoir récupéer les informations d'Alice sans connaitre son mot de passe. Pour cela, on ajoute les caractères : ";--"
Cela va avoir pour effet de terminer la requète (avec le ";" qui est le symbole de fin de requète), et commenter la suite de la requète (avec le smbole "--"). Cette requète va alors seulement récupérer les informations d'Alice et ne va pas effectuer la vérification du mot de passe, car celui-ci est en commentaire et ne sera donc pas compilé.
Connexion avec mot de passe toujours vraie :
<<Image exemple injection dans un formulaire avec mot de passe>>
SELECT * FROM Users WHERE name='Alice' AND password = 'random' or '1=1'; --;
Ici, on injecte du SQL dans le formulaire de saisie du mot de passe. En effet, on tape n'importe quelle mot de passe associé à Alice (vu qu'on ne le connait pas), puis on ajoute : or '1==1';--.
Ceci a pour effet d'ajouter une condition a notre requète. On vérifie d'abord que le mot de passe d'Alice est correcte, ce qui est bien évidement pas le cas, ou alors on regarde si 1 a bien pour valeurs 1 ce qui est toujours le cas, 1 = 1 donc va renvoyer Vraie. Grace a cette injection, la requète va alors valider la saisie du faux mot de passe, et donc récupérer toute les informations liées à Alice.
Les risques ?
Récupération des informations personnels
Reprennont la requète précédente :
SELECT * FROM Users WHERE name='Alice'; -- 'AND password = 'xxx';
Cette requète permet de récupérer toute les informations sur l'utilisateurs Alice.
Par ailleurs, rien ne nous empêche de récupérer les informations d'autre utilisateurs tels que Bob ou Charlie.. On a donc accès a toute les informations sur chaque utilisateurs présent dans la base de donnée.
De plus, certaine informations peuvent être confidentiel, car l'utilisateurs récupère tout, aussi bien son nom que son numéro de carte bleu.
Supression de toute la base de donnée
SELECT * FROM Users WHERE name='Alice';DROP ALL TABLES;-- 'AND password = 'xxx';
Voici un autre exemple d'injection de code SQL. Ici, on ne se préoccupe pas des saisies demandé dans les champs. Le but de cette requète est de tout détruire dans la base de donnée. Pour cela on entre un nom d'utilisateurs suivie d'un ";", ce qui va terminer la requète SQL. Puis ensuite on injecte une requète complète dans le formulaire : DROP ALL TABLES.
Cette requète a pour effet de supprimer toute les tables présentes dans la base de donnée, donc supprimer toutes les informations présentes dans la base de donnée.