Les injections SQL

L’injection SQL est une famille de failles, basée sur le langage SQL qui permet d’agir sur les bases de données (BDD).
Elle permet d’injecter, dans une requête SQL, une partie de code potentiellement compromettant.


L’injection SQL fait partie des attaques les plus courantes.

Avertissement :
Utiliser les techniques présentées sur ce blog, sur des systèmes qui ne vous appartiennent pas est ILLEGAL et peut vous exposer à de lourdes sanctions.

Si vous souhaitez vous exercer, vous devez le faire sur un système qui vous appartient, ou avec un accord écrit du propriétaire.

Je ne pourrais en aucun cas être tenu pour responsable de vos actes.

Exemples d’injections

Lors du login d’un utilisateur, la requête effectuée est de la forme :

SELECT uid FROM Users WHERE name = '(nom)' AND password = '(mot de passe hashé)';

Si je me connecte sur un site la requête sera :

SELECT uid FROM Users WHERE name = 'Angrypingu' AND password = '5f4dcc3b5aa765d61d8327deb882cf99';

Le mot de passe (password) est ici hashé (chiffré) en MD5.

Si le script PHP qui exécute la requête ne vérifie pas les entrées, il est alors possible de modifier les requêtes.

Pour en savoir plus sur les hashes et chiffrements, consultez cet article.

Bloquer l’exécution

En SQL les caractères -- marquent le début d’un commentaire.
Cela signifie que la suite de la requête ne sera pas exécutée.

Ainsi si je tape comme login Angrypingu';--, la requête devient :

SELECT uid FROM Users WHERE name = 'Angrypingu';--' AND password = '4e383a1918b432a9bb7702f086c56596e';

Si la faille est présente, on peut alors utiliser n’importe quel mot de passe.

La tautologie : Les requêtes toujours vraies

Si nous entrons comme mot de passe ' or 1 --, la requête devient :

SELECT uid FROM Users WHERE name = 'Angrypingu' AND password = '' or 1 --';

Ici, le script va simplement vérifier si 1 est vrai au lieu de vérifier le mot de passe.

Solutions / mitigations

Échapper les caractères spéciaux

Il est possible d’échapper (éviter la prise en compte) des caractères spéciaux.
Pour cela, on utilise l’anti-slash .

La fonction PHP mysqli_real_escape_string permet de modifier ' -- en ' --

L’échappement peut aussi se faire (selon le système de BDD utilisé) en doublant les apostrophes.

La marque de commentaire fera alors partie de la chaîne, et le serveur SQL répondra que l’utilisateur n’existe pas.

La fonction addslashes ne suffit pas pour empêcher les injections via les variables numériques, qui ne sont pas encadrées d’apostrophes ou de guillemets.

Exemple :

SELECT ... FROM ... WHERE numero_badge = $numero AND code_4_chiffre = $code;

Cette injection va fonctionner si $numero contient 0 or 1 --

Pour éviter cela, il est possible de vérifier la variable avec ctype_digit. On peut aussi transformer la variable en entier avec int.
De cette façon la variable 0 or 1 -- deviendra 0 et l’injection échouera.

Utilisation de requêtes préparées

Il est aussi possible d’utiliser des requêtes préformatées, ce qui empêche le code injecté dans les paramètres, d’être interprété.

De nombreux frameworks sont équipés d’un ORM qui se charge de préparer les requêtes.


Dans un prochain article nous verrons comment exploiter les injections SQL.

En attendant, retrouvez tous nos sujets : Hacking, Dev, Sécu.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *