Injection SQL
Principe
Une injection SQL est une attaque qui consiste à insérer un code SQL malveillant dans une requête SQL afin de manipuler la base de données. Cela peut permettre à un attaquant d'accéder à des données sensibles, de modifier ou de supprimer des données, ou même de prendre le contrôle total de la base de données.
Pour éviter les injections SQL, il est important de se rappeler qu'il ne faut jamais faire confiance aux données fournies par l'utilisateur. Par conséquent, il ne faut jamais construire de requêtes SQL en concaténant des chaînes de caractères. Au lieu de cela, il est préférable d'utiliser des paramètres dans les requêtes SQL.
Exemple / demo
Si dans l'exemple précédent, au lieu d'utiliser des paramètres dans la requète SQL, on avait construit la requête SQL en concaténant des chaînes de caractères, on aurait pu avoir quelque chose comme :
@route('/ingredients')
def ingredients():
q = request.query.get('q', '')
#...
cursor.execute(f"""
SELECT id, name
FROM ingredients
WHERE UPPER(name) LIKE '%{q.upper()}%'
""")
#...
Dans ce cas, si l'utilisateur entre Tomate' OR 1=1 --, la requête exécutée
sera :
SELECT id, name FROM ingredients WHERE UPPER(name) LIKE '%TOMATE' OR 1=1 --%'
Ce qui va renvoyer tous les ingrédients de la base de données, car 1=1 est
toujours vrai. Le -- permet de commenter le reste de la requête, ce qui évite
les erreurs de syntaxe.
Avec des injections SQL plus complexes, il est possible d'accéder à l'ensemble de la base de données, à son schéma, de la modifier, de la supprimer, etc.. Un outil permettant d'exploiter les injections SQL est sqlmap. Pour l'installer, il suffit de cloner le dépôt :
git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
cd sqlmap-dev
Puis de l'exécuter avec l'url de l'application web en argument :
python sqlmap.py 'http://localhost:8080/ingredients?q=Tomate' # ...
Sqlmap va alors chercher les injections SQL possibles et essayer de les exploiter. Une fois l'injection trouvée, il est possible de l'utiliser pour extraire les données de la base.
Exemple en "video" sur notre application :
screencast session sqlmap. On
ajoute le --delay 0.1 pour éviter de surcharger le serveur avec trop de
requêtes simultanées, en mode debug ça ne passe pas terriblement.
En quelques secondes, sqlmap a trouvé et exploité l'injection SQL. Il a pu extraire les données de la base de données, y compris le schéma de la base de données, les tables et les colonnes.
Pour info, les logs serveur associés à cette session.