Les injections SQL sont un groupe de méthodes d'exploitation de faille de sécurité d'une application communiquant avec une base de données SQL.
Ils permettent entre autres à un utilisateur malveillant d'interagir avec les requêtes envoyées par cette application.
Cette interaction survient la plupart du temps par l'entrée de morceaus de requêtes dans les divers champs de l'application. Une application vulnérable exécutera la requête compomise causant des dommages irréversibles.
L'individu malveillant pourra entre autre :
- Extraire des données utilisateur (noms, adresses, numeros de cartes de crédit)
- Contourner l'authentification (Se connecter sur les comptes d'autres utilisateurs voir de l'administrateur)
- Modifier ou Supprimer des tables , voir l'entiereté de la base de donnée.
Considérons ce site vulnérable fourni par IBM comme un exemple.
les variables Username et Password contienent les entrés de lutilisateur:UserName = getRequestString("azerty");
Password = getRequestString("1234");
La requête derriere est telle:
SELECT id FROM Users WHERE name = ' azerty ' AND password = ' Hashed(1234)';
Si le UserName
existe et que le Password
lui correspond , un id
est renvoyé, le compte existe , sinon les entrées sont érronnés.
Un individu malveillant
Pourrai entré dans les champs du UserName
un or payload
Et la requête envoyée a la base de donnée sera donc :
SELECT id FROM Users WHERE name = ' admin' or '1' = '1 ' AND password = ' Hashed(Password)';
L'utilisateur sera connecté sur le compte de l'admin
s'il existe et si '1' = '1' , meme si le Password
est erroné.
Voici une démo d'une injection SQL avec différents types de payloads
Les attaques du type Injection quoiqu'étant l'une des failles de sécurité web les plus connues ont été classée troisième en 2021 par L' Open Web Application Security Project .
94 % des applications ont été testées pour une forme d'injection avec un taux d'incidence maximal de 19 %, un taux d'incidence moyen de 3 % et 274 000 occurrences.
L'une des meilleurs options permettant d'éviter les attaques par injection SQL, quelle que soit la base de données que vous utilisez, est de séparer les les variables entrées par l'utilisteur de la syntaxe de notre requête SQL, afin que les variables restent des variables et ne soient jamais interprétées comme des commandes par l'analyseur SQL.
Faire transiter les requêtes par des API saines comme :
L'instruction SQL que vous transmettez à prepare
est analysée et compilée par le serveur de base de données. En spécifiant des paramètres (comme le ?
ci dessus), vous indiquez au moteur de base de données où vous souhaitez filtrer.
Ensuite, lorsque vous appelez execute
, l'instruction préparée est combinée avec les valeurs de paramètre que vous spécifiez.
L'avantage avec cette technique est que les valeurs des paramètres sont combinées avec la requête compilée( Ce qui se fait au moment ou vous appellez prepare
), et non avec les chaines de charactere la constituant.
L'injection SQL fonctionnant en incitant le script à inclure des chaînes malveillantes lorsqu'il crée la requête SQL à envoyer à la base de données, en envoyant le SQL réel séparément des paramètres, tous les paramètres que vous envoyez lors de l'utilisation d'une instruction préparée seront simplement traités comme des chaînes de charactere (bien que le moteur de base de données puisse effectuer une certaine optimisation afin que les paramètres puissent également se retrouver sous forme de nombres).
Un or payload , un comment payload ou n'importe quelle autre syntaxe du type Injection SQL entrée dans les champs d'une page de connexion utilisant des requêtes via PDO sera infructueuse.
L' OWASP fournit plusieurs techniques permettant d'éviter les injections SQL et toutes sortes d'attaques du type Injection et de sécuriser vos applications.