Sécurité des applications Web - Menaces et contre-mesures

Auteur: Mohamed CHINY Durée necessaire pour le cours de Sécurité des applications Web - Menaces et contre-mesures Niveau recommandé pour le cours de Sécurité des applications Web - Menaces et contre-mesures Supports vidéo non disponibles pour ce cours Exercices de renforcement non disponibles pour ce cours Quiz non disponibles pour ce cours

Leçon 3: L'injection SQL

Toutes les leçons

L'injection SQL (ou faire passer du code SQL inaperçu au sein du code source)

Définition

L'injection SQL demeure l’une des attaques les plus emblématiques de la sécurité applicative. Son principe, à la fois simple et ingénieux, en fait une technique extrêmement populaire auprès des attaquants. Déjà en 2017, elle figurait en tête du Top 10 OWASP, preuve de son impact majeur sur les applications web. Et malgré l’évolution des pratiques de développement et des outils de protection, elle reste classée parmi les risques critiques dans le Top 10 OWASP 2025, confirmant qu’elle représente toujours une menace sérieuse pour la confidentialité, l’intégrité et la disponibilité des systèmes.

L’attaque par injection SQL repose sur le fait qu’un pirate parvient à insérer son propre code SQL dans une requête envoyée au serveur. Ce code malveillant se combine alors avec les requêtes légitimes de l’application ou du site web, ce qui détourne le fonctionnement attendu et permet d’accéder à des données sensibles ou de manipuler la base. Les applications vulnérables sont celles qui reposent sur une base de données SQL et qui ne filtrent pas correctement les entrées utilisateur. En revanche, un site qui ne s’appuie pas sur une base SQL n’est pas exposé à ce type d’attaque, car l’injection SQL exploite exclusivement les failles liées aux systèmes de gestion de bases de données relationnelles.

Quand cette attaque réussit, elle peut avoir des conséquences désastreuses sur le site Web comme par exemple:
  • L'accès à un espace non autorisé via une fausse authentification
  • Suppression des données d'une manière frauduleuse
  • Vol de données confidentielles enregistrées dans la base de données
  • Destruction ou atteinte à l'intégrité de la base de données

Exploitation

L'attaque repose sur l'exploitation des entrées d'un site Web comme les champs de formulaires ou la barre d'URL. Par exemple, quand on demande à l'utilisateur de s'authentifier en entrant un login et un mot de passe, si celui-ci était un pirate aux mauvaises intentions, alors au lieux de saisir du texte normal il saisirait des séquences de codes SQL qu'il soumettrait au serveur. Si le site présente une vulnérabilité à l'injection SQL alors il se peut que le code SQL injecté s'exécute et donne lieu à un comportement inattendu comme avoir accès illégalement à l'espace confidentiel.

Par exemple, imaginez que le code SQL (encapsulé dans le code PHP) qui permet de vérifier si un login et un mot de passe sont valides est le suivant:
select * from table_users where login='$_POST["login"]' and pass='$_POST["pass"]'
Notez que $_POST["login"] et $_POST["pass"] représentent les textes que l'utilisateur a saisi dans les champs de formulaire dédiés à cet effet.

Cette requête SQL retournera toutes les lignes (en général y'en aura qu'une seule) où les champs 'login' et 'pass' contiendront respectivement le login et le mot de passe saisis par le client.

Maintenant imaginez avec moi que l'utilisateur (malhonnête) a saisie dans le champ login la chaine admin' -- , alors notre requête SQL deviendra
select * from table_users where login='admin'--' and pass='$_POST["pass"]'
Et puisque le double tiret (--) constitue un commentaire SQL, tout le code qui le suivra sera ignoré au moment de l'exécution ce qui revient à exécuter le code suivant:
select * from table_users where login='admin'
Et voilà, le code SQL de l'application a été modifié suite à cette injection et ne vérifie plus de mot de passe, il se contente seulement de vérifier si le login vaut admin. Si un tel login existe dans la base de données alors le pirate sera authentifié et accédera à l'espace admin.
Il s’agit là de l’exemple le plus simple d’une injection SQL, mais un pirate peut utiliser d’autres formes plus avancées, comme l’injection error‑based, union‑based, blind ou encore time‑based. Chacune de ces techniques repose sur le même principe : insérer du code SQL malveillant dans une requête, mais avec des méthodes différentes pour contourner les protections et obtenir des informations. Si le serveur présente la vulnérabilité, ces requêtes ont toutes les chances de s’exécuter et de détourner le fonctionnement attendu de l’application.

Comment s'en protéger?

Au niveau du code PHP

Il existe plusieurs méthodes qui permettent de détourner les tentatives d'injection SQL et je vais citer quelques unes:

Filtrer les entrées de l'utilisateur:

A la base, tout ce que l'utilisateur peut soumettre au serveur est considéré comme contenu étranger et potentiellement hostile. Donc, avant de laisser passer ses entrées, il faut les filtrer. On peut tout simplement échapper les caractères spéciaux contenus dans les chaines de caractères soumises en utilisant des fonctions PHP comme addslashes() ou mysql_real_escape_string(). On peut également appliquer les expressions régulières pour vérifier si la chaine représente un tel motif comme par la fonction preg_match() et aussi vérifier la longueur de la chaine par la fonction strlen().

Utiliser l'objet PDO:

Dans le chapitre dédié à l'objet PDO (PHP Data Object), j'ai mentionné quelques vertus de cet objet. Celui qui nous intéresse ici c'est qu'il apporte une immunité totale contre les injections SQL si on sépare les données du traitement (les requêtes préparées avec les marqueurs interrogatifs ou paramètres nommés).

Faire une authentification en deux temps:

Au lieu de vérifier le login et le mot de passe dans la même requête, on sépare ce traitement en deux. On demande d'abord le login, et si celui-ci est correcte on demande ensuite le mot de passe.

Au niveau de la configuration du serveur

Dans ce cas, il suffit de modifier le fichier de configuration du moteur PHP, appelé php.ini. Ce fichier texte contient un ensemble de directives qui permettent de personnaliser le comportement de PHP selon les besoins de l’application. Pour illustrer, on peut agir sur la directive magic_quotes_gpc, qui ajoute automatiquement des antislashs aux données reçues via GET, POST ou COOKIE. En ajustant cette directive dans le fichier php.ini, on contrôle directement la manière dont PHP traite les entrées utilisateur, ce qui peut avoir un impact sur la sécurité et la gestion des données. Pour cette partie on va tout simplement changer la directive magic_quotes_gpc comme ceci:
magic_quotes_gpc = On
La directive magic_quotes_gpc a été retirée des versions modernes de PHP (supprimée définitivement depuis PHP 8). En effet, elle ne constituait pas une véritable protection contre les attaques par injection SQL et pouvait même donner une fausse impression de sécurité. Les bonnes pratiques actuelles recommandent plutôt à l’utilisation de requêtes préparées pour sécuriser efficacement les interactions avec une base de données.