Le Laboratoire Virtuel & Terminal Pratique est en ligne :

Ouvrir le Labo
Volume 6 : Web, Architecture HTTP & Bases de Données SQL/Module 2 : Bases de Données SQL & Injections (SQLi)

LAB 05 : Anatomie des Injections SQL & Requêtes Préparées

Labo Virtuel >_

LAB 05 : Anatomie des Injections SQL & Requêtes Préparées



L'Injection SQL (SQL Injection - SQLi) figure depuis plus de 20 ans parmi les vulnérabilités les plus dévastatrices répertoriées par l'OWASP (Catégorie A03:2021 - Injection). Elle permet à un attaquant de briser le contexte de données pour injecter des commandes SQL directement interprétées par le moteur de base de données.

---

1. La Cause Première : La Concaténation Naïve de Chaînes



L'erreur fondamentale réside dans l'assemblage dynamique d'une requête SQL par simple concaténation de texte avec des entrées fournies par l'utilisateur :

``python

❌ CODE CRITIQUEMENT VULNÉRABLE :

def authentifier_utilisateur_vulnerable(username_input: str, password_input: str): # L'entrée utilisateur est directement collée dans la chaîne SQL ! requete = f"SELECT id, role FROM users WHERE username = '{username_input}' AND password = '{password_input}'" return db.execute(requete)
`

Si un attaquant saisit dans le champ utilisateur :
`sql admin' -- ` La requête exécutée par la base de données devient : `sql SELECT id, role FROM users WHERE username = 'admin' --' AND password = '...' ` Les caractères -- (ou # sous MySQL) indiquent un commentaire SQL. Toute la clause de vérification du mot de passe est purement et simplement ignorée ! L'attaquant se connecte instantanément en tant qu'administrateur sans connaître le mot de passe.

---

2. Les Différentes Familles d'Injections SQL



` [ INJECTIONS SQL ] / | \ / | \ [ IN-BAND ] [ INFERENTIAL ] [ OUT-OF-BAND ] / \ (BLIND) (DNS / HTTP) UNION-Based Error-Based / \ Boolean-Based Time-Based `

A. L'Injection In-Band UNION (UNION SELECT)

Permet de joindre le résultat de la requête légitime avec les tables confidentielles du système : `sql ' UNION SELECT null, username, password, email FROM users-- `

B. L'Injection Blind Temporelle (Time-Based Blind)

Lorsque l'application n'affiche aucun message d'erreur ni aucune donnée à l'écran, l'attaquant force la base de données à marquer une pause temporelle pour déduire les données caractère par caractère :
`sql ' OR (SELECT CASE WHEN (SUBSTR(password,1,1)='a') THEN pg_sleep(5) ELSE pg_sleep(0) END FROM users WHERE username='admin')-- ` Si la page met 5 secondes à répondre, le premier caractère du mot de passe de l'administrateur est validé comme étant la lettre 'a' !

---

3. Le Remède Définitif : Les Requêtes Préparées (Paramétrage)



La seule méthode de remédiation infaillible et pérenne est l'utilisation stricte de Requêtes Préparées avec Paramètres Liés (Prepared Statements / Parameterized Queries) :

`python

✅ CODE TOTALEMENT SÉCURISÉ :

def authentifier_utilisateur_securise(username_input: str, password_input: str): # La requête est pré-compilée par le SGBD avec des marqueurs de position '?' sql = "SELECT id, password_hash, role FROM users WHERE username = ?" curseur = db.cursor() # La valeur est transmise séparément dans le tuple de paramètres curseur.execute(sql, (username_input,)) user = curseur.fetchone() if not user: return None # Vérification sécurisée du mot de passe avec sel cryptographique import hashlib, secrets if secrets.compare_digest(hashlib.sha256(password_input.encode()).hexdigest(), user["password_hash"]): return user return None
`

Dans une requête préparée, le moteur SQL compile la syntaxe de la requête avant de recevoir les données. Même si l'entrée utilisateur contient des guillemets, des apostrophes ou
UNION SELECT`, le moteur SQL traite l'intégralité de l'entrée comme une valeur littérale (donnée pure) et non comme du code exécutable. L'injection est mathématiquement impossible.
Informations
Formatlab
Durée55 min
StatutEn cours
Laboratoire Virtuel Pratique

Pratiquez cette le?on dans le Terminal Linux et l'ex?cuteur WebAssembly Python en direct.

Ouvrir dans le Labo >_