Qu'est-ce qu'une faille Structured Query Language injection ?


De nombreux développeurs web ne sont pas conscients des possibilités de manipulation des requêtes SQL et supposent que ces dernières sont toujours fiables.

Comme son nom l’indique, l’injection SQL (ou SQLi) est une méthode d’exploitation de faille de sécurité d’une application possédant des interactions avec une base de données. Le principe est d’injecter, dans une requête, du code SQL malveillant qui viendra modifier l’effet escompté et ainsi compromettre l’intégrité des données présentes dans la base. Cette technique est très souvent utilisée pour contourner les mécanismes d'authentification et d'autorisation d'une application web.

Une faille SQLi peut avoir de lourdes conséquences car un hackeur peut avoir un accès non autorisé aux données sensibles. Il sera en mesure de lire la base de données, y enregistrer de nouvelles données ou exécuter du code malveillant. Quand on connaît la valeur et l’importance des données il serait dommageable pour un site de subir une telle cyberattaque.

Exemple :
Nous avons choisi l’exemple du système d’authentification pour illustrer la vulnérabilité mais cette dernière peut être présente partout sur un site web. Dès qu’il y a un champ « input » il y a un risque d’injection SQL si les requêtes ne sont pas protégées.

Lorsqu’un utilisateur souhaite se connecter sur un site web dynamique il doit renseigner son identifiant ainsi que son mot de passe dans des champs spécifiques (de type input). Le système interne va exécuter une requête avec les données saisies afin de vérifier que l’utilisateur est bien présent dans la base de données, c’est-à-dire que son identifiant et son mot de passe sont valides.

La requête SQL exécutée par le système est :

SELECT user_id
FROM Users
WHERE name = '(identifiant)' AND password = '(Mot de passe hashé)';

Si le script serveur (PHP, JAVA, ASPX, ...) exécutant la requête ne vérifie pas les données entrantes, il est alors possible d’attaquer la requête en ajoutant les caractères suivants dans le champ identifiant : ';--
La requête devient alors :

SELECT user_id
FROM Users
WHERE name = '(identifiant)'; --' AND password = '(Mot de passe hashé)';

Les caractères -- marquent le début d'un commentaire en SQL. La deuxième condition du « WHERE » ne sera donc pas exécutée. L’utilisateur peut alors se connecter avec n’importe quel mot de passe à partir du moment où l’identifiant saisi est bien présent dans la base de données.

Il est aussi possible de tromper le script SQL sur le mot de passe en saisissant dans le champ prévu à cet effet le code suivant : ' or 1 --

L'apostrophe indique la fin de la zone de frappe de l'utilisateur, le code « or 1 » demande au script si 1 est vrai, or c'est toujours le cas. -- indique le début d'un commentaire. Le système va vérifier si ce que l'utilisateur tape est vrai, il verra que 1 est vrai, et l'attaquant sera connecté.


Comment se protéger contre les failles Structured Query Language injection ?


Afin de se protéger contre les failles SQLi, il est préférable d’utiliser un système de requêtes préparées (PDO pour PHP par exemple). La requête est compilée avant d’être exécutée pour s’assurer qu’elle ne contient pas de caractères d’échappement.