Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

L'injection SQL : comprendre et corriger

Après cette leçon: Je peux écrire une requête SQL paramétrée qui ne peut pas être détournée.

Leçon de 50 min4 commandesLab d’injection SQL : attaquer une recherche faible, corriger la requête et prouver la correction

Une barre de recherche peut-elle voler une base ?

L'injection SQL est une attaque où un texte tapé dans un formulaire est pris pour une commande par la base de données. Elle existe depuis plus de vingt ans et elle marche encore, car une seule ligne de code oubliée suffit.

Aujourd'hui, tu comprends pourquoi, et tu apprends à la corriger.

À la fin de cette leçon

Remarque

Je peux écrire une requête SQL paramétrée qui ne peut pas être détournée.

Mots clés

MotCe que ça veut direExemple
Requête SQLune demande écrite à une base de donnéesSELECT nom FROM eleves
Injection SQLdu texte tapé qui change le sens de la requête
Concaténationcoller des morceaux de texte bout à bout
Requête paramétréeune requête où les valeurs arrivent à part
Entréetout ce qu'un visiteur peut taper ou envoyer

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

La règle de ce lab

Important

Tu travailles seulement sur ta propre copie de la boutique du lab, avec la permission de ton enseignant. Ne teste jamais une injection sur un vrai site : même pour voir, c'est interdit sans accord. On apprend l'attaque pour écrire du code qui lui résiste.

Comment un texte devient une commande

Un site de lycée vérifie un nom avec une requête. Le code colle le texte tapé dans la requête, comme un morceau de phrase.

Si le texte contient des signes que SQL comprend, comme l'apostrophe, il sort de la place prévue et devient une partie de la commande. La base ne sait plus où finit la phrase du programmeur.

Exemple : la requête construite par concaténation

Texte tapéRequête reçue par la baseEffet
CamilleSELECT * FROM eleves WHERE nom = 'Camille'Un seul élève
Camille' OR 1=1 --SELECT * FROM eleves WHERE nom = 'Camille' OR 1=1 --'Tous les élèves : 1=1 est toujours vrai
L'HopitalSELECT * FROM eleves WHERE nom = 'L'Hopital'Une erreur : l'apostrophe coupe le texte

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Une erreur fréquente

Attention

Beaucoup pensent qu'il suffit de retirer les apostrophes du texte tapé. Ce n'est pas assez : il existe d'autres astuces, et on casse les vrais noms comme L'Hopital. La bonne défense est de ne jamais coller le texte dans la requête.

Comment corriger : la requête paramétrée

Une requête paramétrée écrit la requête avec des places vides, notées ?. Les valeurs sont envoyées à part.

La base lit d'abord la requête, puis y met les valeurs comme de simples textes. Une apostrophe reste une apostrophe : elle ne peut plus devenir du code.

Exemple : chercher un nom avec un paramètre

Code: python
import sqlite3

connexion = sqlite3.connect(":memory:")
connexion.execute("CREATE TABLE eleves (nom TEXT)")
connexion.execute("INSERT INTO eleves VALUES ('Camille')")
connexion.execute("INSERT INTO eleves VALUES ('Louis')")

# Le texte tapé arrive à part, à la place du point d'interrogation.
texte = "Camille' OR 1=1 --"
lignes = connexion.execute("SELECT nom FROM eleves WHERE nom = ?", (texte,)).fetchall()
print(lignes)  # Change texte en "Louis" et relance.

Avant de commencer

Remarque

Appuie sur Start the lab et attends que la boutique soit prête. La boutique s'appelle Corner Shop : c'est le service app, sur le port 8000. Dans cette leçon, tu la regardes seulement. Le lab te demandera ensuite de la réparer.

Lis la page d'accueil de la boutique

Commande
curl -s http://app:8000/

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Fais une recherche normale : pen

Commande
curl -sG --data-urlencode "q=pen" http://app:8000/search

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Fais une autre recherche normale : mug

Commande
curl -sG --data-urlencode "q=mug" http://app:8000/search

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Demande une page inconnue, lis le code

Commande
curl -s -o /dev/null -w "%{http_code}\n" http://app:8000/inconnu

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Que montre une recherche normale ?

Une recherche normale renvoie les produits dont le nom contient le texte, un par ligne avec son prix. Le site n'a rien de suspect quand on s'en sert bien.

Le défaut est dans la façon dont le code construit la requête, pas dans ce qu'on voit. Dans le lab, tu cherches comment le code collerait le texte, puis tu le répares.

Pour aller plus loin : limiter les dégâts

Même bien écrit, un site peut avoir une autre faille. Une deuxième défense est de donner au site un compte de base de données qui ne peut lire que les tables dont il a besoin.

Pourquoi cela limite-t-il les dégâts si une injection passe quand même ? Réponds avec les mots table et droits.

À propos de ce labo et de sa source: Lab d’injection SQL : attaquer une recherche faible, corriger la requête et prouver la correction

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.