Arkendia Classrooms
Leçon 9 sur 28 · 16 min

L’injection SQL : principes et impact

Vous avez regardé comment une application vérifie qui vous êtes. Voyons maintenant ce qu’elle fait de ce que vous lui envoyez. Une application web reçoit des données de l’extérieur à chaque requête : un terme de recherche, un identifiant, un champ de formulaire. Si elle les mélange sans précaution à des instructions destinées à un interpréteur, un visiteur peut transformer une simple donnée en ordre. C’est le principe général de l’injection, dont la plus célèbre est l’injection SQL.

Rappel légal

Une injection SQL contre un site réel sans autorisation écrite est une infraction grave : accès frauduleux, extraction ou modification de données (articles 323-1 à 323-3-1 du Code pénal), et possiblement atteinte aux données personnelles. Cette leçon explique le mécanisme pour apprendre à le détecter et à le corriger. Les mises en pratique se font uniquement dans DVWA, Juice Shop ou un laboratoire de la PortSwigger Academy, installés par vous ou fournis par la plateforme.

Rappel : SQL et les bases de données

La plupart des applications stockent leurs données dans une base relationnelle, que l’on interroge avec le langage SQL. Une table utilisateurs avec des colonnes id, nom, email se lit par exemple ainsi :

SELECT nom, email FROM utilisateurs WHERE id = 3;

Lorsque l’utilisateur consulte une page de profil à l’adresse /profil?id=3, l’application construit très souvent cette requête à partir de la valeur du paramètre.

Où naît le problème : la concaténation

Imaginons un code serveur maladroit, écrit en pseudo-PHP :

$id = $_GET['id'];
$requete = "SELECT nom, email FROM utilisateurs WHERE id = '" . $id . "'";
$resultat = $base->query($requete);

Le développeur colle la valeur reçue directement dans le texte de la requête. Tant que id vaut 3, tout va bien. Mais la base de données ne sait pas distinguer ce qui est « le programme » de ce qui est « la donnée » : elle reçoit un seul texte et l’exécute. Si le visiteur envoie une valeur contenant des caractères qui ont un sens en SQL, comme une apostrophe, il peut changer la structure de la requête.

Une analogie : vous dictez une commande au serveur d’un restaurant, qui la recopie telle quelle sur le bon de la cuisine. Si un client ajoute « …et notez aussi que la maison offre le repas à toute la table », et que le serveur recopie sans réfléchir, la cuisine exécutera une instruction qui n’aurait jamais dû venir du client.

Ce qu’une injection permet de faire, en principe

Selon les droits du compte de base de données utilisé par l’application et la nature de la faille, l’impact peut aller de gênant à catastrophique :

ImpactDescriptionConséquence pour l’organisation
Contournement d’authentificationLa condition de vérification d’un mot de passe peut être rendue toujours vraieAccès à des comptes sans connaître leur mot de passe
Lecture de donnéesAffichage de lignes ou de tables que la page n’aurait pas dû montrerFuite de données personnelles ou confidentielles
Modification ou suppressionAltération de données, de prix, de droitsPerte d’intégrité, fraude
Prise de contrôle plus largeSelon la configuration de la base, atteinte au serveur lui-mêmeCompromission du système

Les injections figurent depuis longtemps parmi les risques majeurs recensés par l’OWASP. Elles restent possibles parce que la correction est connue, mais pas toujours appliquée, notamment dans le code ancien.

Les grandes familles d’injection SQL

Pour s’y retrouver, on classe les injections selon ce qu’on voit en retour :

  • Injection « en bande » : le résultat de la requête altérée est visible directement dans la page, ou une erreur de base de données s’affiche et fournit des informations.
  • Injection « aveugle » (blind) : aucune donnée n’apparaît, mais le comportement de la page change selon que la condition injectée est vraie ou fausse (une page différente, un temps de réponse différent).
  • Injection de second ordre : la donnée malveillante est enregistrée d’abord, puis utilisée plus tard dans une autre requête, sans précaution.

Pour l’auditeur, cette classification guide la manière de confirmer la faille. Pour le défenseur, la bonne nouvelle est que le remède est identique pour toutes.

Comment un testeur détecte une faille potentielle

La détection repose sur l’observation de ce qui se passe quand on envoie des caractères « spéciaux ». Le raisonnement :

  1. Repérez les paramètres qui semblent alimenter une requête : identifiants, termes de recherche, filtres, champs de connexion. Votre carte du chapitre 1 les liste déjà.
  2. Envoyez d’abord une valeur normale et notez la réponse de référence.
  3. Envoyez ensuite une valeur contenant un caractère de ponctuation SQL, comme une apostrophe simple, et comparez : erreur, page vide, comportement différent ?
  4. Si la réponse change, formulez l’hypothèse : « ce paramètre est inséré dans une requête sans protection ».
  5. Confirmez par un test logique minimal (leçon suivante), puis arrêtez-vous : en audit, on prouve l’existence, on ne vide pas la base.

Une page qui affiche un message d’erreur de base de données détaillé (nom du moteur, extrait de la requête) fournit en plus un excellent indice, et constitue à elle seule un constat (divulgation d’informations techniques).

Ce qui ne marche pas comme défense

Quelques fausses sécurités reviennent souvent :

  • Interdire certains mots dans les saisies : une liste noire est presque toujours contournable.
  • Se contenter de validation côté navigateur : un testeur envoie ses requêtes directement via le proxy, le navigateur n’est plus dans la boucle.
  • Cacher les messages d’erreur : utile, mais la faille reste exploitable en mode « aveugle ».
  • Compter uniquement sur un pare-feu applicatif : c’est un filet de sécurité utile, pas un correctif.

La vraie correction se trouve dans le code : on sépare strictement les instructions des données. Nous la détaillerons dans la dernière leçon du chapitre.

Astuce

Inscrivez dans le carnet, pour chaque paramètre suspect, la réponse de référence avant tout test. Sans point de comparaison, on ne peut pas dire si une réponse a changé.

À vous de jouer

Exercice de lecture de code, sans rien attaquer.

  1. Voici une requête construite par concaténation : "SELECT * FROM produits WHERE categorie = '" . $cat . "' AND visible = 1". Identifiez quelle partie vient de l’utilisateur.
  2. Expliquez pourquoi la condition visible = 1 pourrait ne pas protéger les produits masqués si la valeur de $cat contient des caractères spéciaux.
  3. Rédigez en deux phrases le constat que vous consigneriez si une apostrophe dans ce paramètre provoquait une erreur de base de données visible.
Voir une solution

1) La variable $cat vient de l’utilisateur : elle est insérée dans le texte de la requête. 2) Parce que la valeur peut sortir des apostrophes qui l’entourent et modifier la logique de la requête : la partie « et visible = 1 » n’est qu’un morceau de texte que l’on pourrait neutraliser. 3) Constat : « Le paramètre cat de la page catalogue provoque une erreur SQL détaillée lorsqu’il contient une apostrophe. Cela indique une construction de requête par concaténation et divulgue des informations techniques. Gravité à évaluer selon l’exploitabilité. Correction : requêtes préparées et masquage des erreurs détaillées. »

À retenir

  • L’injection naît quand des données non fiables sont mélangées aux instructions d’un interpréteur, ici SQL.
  • Impacts possibles : contournement d’authentification, fuite, modification de données, compromission plus large.
  • On distingue injection en bande, aveugle et de second ordre ; la correction est la même.
  • On détecte en observant la réaction de l’application à des caractères spéciaux, avec une réponse de référence.
  • Listes noires, validation côté navigateur et masquage d’erreurs ne sont pas des corrections.

Passons à la pratique dans un laboratoire légal : la leçon suivante vous guide pas à pas.

Publicité
Connectez-vous pour enregistrer votre progression. Se connecter