Qu’est-ce qu’une injection SQL et comment puis-je l’éviter ?

Cela fait déjà 14 ans que l’on connaît le danger que représente une injection SQL. Pourtant, cela reste un des pires dangers auxquels sont exposés les sites web dynamiques. Cette méthode d’attaque peut en effet causer d’importants dégâts, comme la destruction des données contenues dans votre base de données. Mais de quoi s’agit-il au juste ? Et comment peut-on y faire face ?

1. Qu’est-ce qu’une injection SQL ?

Le web moderne regorge de sites dynamiques, qui sont générés à la volée. Un langage de script tel que PHP récupère du contenu d’une base de données, et le met en forme par le biais d’instructions ou de déclarations. De telles instructions contiennent le code du développeur, ainsi que les données que le visiteur fournit via un formulaire web, comme p. ex. lorsqu’il saisit son nom d’utilisateur et son mot de passe.

Lorsqu’un développeur n’est pas suffisamment vigilant dans ses déclarations, une personne malintentionnée peut glisser du code dans les données qu’elle saisit, ce qui lui permet de faire exécuter d’autres instructions.

En résumé, les hackers utilisent certains caractères ou certaines formules dans le champ de saisie d’un formulaire, de manière à ce que leurs entrées ne soient plus considérées comme de simples chaînes de caractères, mais bien comme des fonctions.

 

Ces signes peuvent p. ex. constituer un danger :

  • * (astérisque) est une instruction qui demande à la base de données SQL d’afficher toutes les colonnes pour la ligne sélectionnée dans la base de données
  • = (égal à) est une instruction qui demande à la base de données SQL de n’afficher que la/les valeur(s) qui correspond(ent) à la chaîne de caractères recherchée
  • ' (guillemet simple) est utilisé pour dire à la base de données SQL où la chaîne de recherche commence ou se termine
  • ; (point-virgule) est utilisé pour dire à l’analyseur SQL que la déclaration actuelle est terminée
  • -- (double tiret) est utilisé pour dire à l’analyseur SQL que le reste de la ligne est un commentaire et ne doit pas être exécuté.

Vous pouvez facilement imaginer les abus pouvant potentiellement découler de l’utilisation de ces signes !

2. Quels sont les dangers d’une injection SQL ?

Une injection SQL consiste donc à ajouter du code supplémentaire aux entrées. Si aucune précaution n’a été prise dans le script pour anticiper de telles situations, le code sera exécuté, avec tous les dangers que cela comporte.

L’attaquant peut :

  • Ajouter, modifier ou lire des données contenues dans la base de données
  • Lire le code source de fichiers se trouvant sur le serveur de bases de données
  • Écrire des fichiers dans la base de données.

 

Voici un exemple qui devrait clairement illustrer cela.

txtUserId = getRequestString("UserId");

txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Ce code est utilisé pour créer une déclaration SQL dont le but est de sélectionner un utilisateur correspondant à un certain identifiant. Mais que se passe-t-il si l’utilisateur ajoute le code suivant en tant que UserID dans le formulaire ?

105 OR 1=1

La déclaration prendra alors la forme suivante :

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

Conséquence : alors que le but initial était de n’afficher qu’une seule ligne, à savoir celle correspondant à l’identifiant de l’utilisateur (UserID) complété lors de la saisie, TOUTES les lignes sont à présent affichées, du fait que la condition OR est toujours vraie (puisque 1=1). Lorsque le tableau Users ne contient pas uniquement des noms d’utilisateurs mais aussi des mots de passe, c’est la catastrophe !

 SQL injection cartoon

3. Comment pouvez-vous vous protéger contre une injection SQL ?

Les trois principales méthodes qui protègeront votre site web contre de telles injections sont les suivantes :

  • Modification des types de données (déterminer à l’avance les types de données que vous attendez pour la variable). S’agit-il d’un entier, d’une chaîne de caractères ou d’un booléen (vrai/faux) ? En PHP, pour un entier, vous pouvez p. ex. utiliser le code suivant :

$id = (int)$_GET['id'];

  • Chaînes échappées (échapper les caractères spéciaux tels que '). En PHP, utilisez pour ce faire la fonction suivante :

mysqli_real_escape_string()

  • Déclarations préparées (définir la structure d’une requête à l’avance). En PHP, vous pouvez créer une déclaration préparée comme ceci :

mysqli_stmt_init

Pour ensuite exécuter la déclaration préparée comme suit :

mysqli_stmt_prepare

 

Si vous désirez en savoir plus, n’hésitez pas à visiter les pages suivantes : modification des types de données, requêtes préparées et W3Schools sur les injections SQL.

Saviez-vous d’ailleurs qu’en choisissant votre hébergement chez Combell, vous bénéficiez de la meilleure sécurité disponible sur le marché ? Et que Combell propose même le patching automatique, qui protège également votre hébergement de SGC (WordPress, Magento, Joomla et Drupal) contre les vulnérabilités les plus récentes ?

 

Découvrez le niveau de protection exceptionnel qu’offre l’hébergement de Combell