Lab d’injection SQL : attaquer une recherche faible, corriger la requête et prouver la correction
Ce lab donne à chaque élève une petite boutique dont la recherche de produits est vulnérable à l’injection SQL. L’élève l’attaque depuis le terminal du lab avec curl, en faisant afficher des produits qui ne sont pas en vente ainsi que les utilisateurs et les mots de passe de la boutique, puis corrige le code dans le conteneur en marche pour que la requête soit paramétrée, redémarre la boutique et voit les mêmes attaques ne rien trouver alors que les recherches normales fonctionnent toujours.
Il est conçu par nous à partir de la seule image publique de Python : il n’y a donc aucune application tierce à attaquer, seulement un court programme à nous, faux à dessein. La seule règle est la règle habituelle d’un lab d’attaque : n’attaquez que votre propre copie. La copie n’a aucune route vers internet ni vers un autre élève, et un élève ne doit jamais diriger un outil vers un site qui n’est pas le sien.
Ce que les élèves apprennent
Comment se produit une injection SQL : un programme colle ce qu’un visiteur a saisi dans le texte de sa question à la base de données, si bien qu’une apostrophe termine la question trop tôt et que la suite est écrite par le visiteur. Ils sortent de la question avec un OR toujours vrai, lisent une autre table avec un UNION, trouvent la ligne responsable et la remplacent par une requête paramétrée, qui envoie la question et la valeur séparément, de sorte qu’une valeur ne peut jamais faire partie de la question. Ils vérifient aussi que la correction n’a pas cassé l’usage normal, ce qui inclut un produit dont le nom contient une apostrophe. Il convient aux unités de programmation sécurisée et de sécurité des applications web, ainsi qu’à leur volet juridique : l’autorisation et le périmètre. Vérifiez la formulation exacte dans l’unité de votre organisme certificateur.
Le lancer dans votre navigateur
La boutique est le service nommé app, et le terminal du lab l’atteint par ce nom. Une commande docker dans le terminal peut consulter, ouvrir, redémarrer et lire les journaux du service du lab : elle ne peut rien créer, télécharger ni supprimer. Le programme est dans un volume nommé, donc ce que l’élève enregistre est encore là après l’arrêt et le redémarrage du lab.
- Ouvrir la page Conteneur. Ouvrez « Créer » dans la barre et choisissez « Lancer un conteneur ». Tout le monde peut ouvrir la page, et le lab Git et le lab SQL se lancent sans compte. Tous les autres labs demandent un compte gratuit : créez-en un, connectez-vous, puis appuyez sur « Démarrer ».
- Trouver le lab. La carte « Laboratoires d’exemple » liste tous les exemples. Trouvez Injection SQL : la trouver et la corriger.
- Appuyer sur Démarrer. « Démarrer » le lance tel quel, en un clic. « Modifier le fichier d’abord » ouvre le fichier compose pour que vous puissiez le changer avant de démarrer.
- L’ouvrir. Sur la page du lab, ouvrez le terminal à côté du lab. Lancez curl -s -G --data-urlencode "q=pen" http://app:8000/search pour chercher dans la boutique, puis faites-lui en montrer trop avec une recherche de x' OR 1=1 -- . docker exec -it app vi /tmp/app/app.py ouvre le programme pour le modifier, docker restart app lance la nouvelle version, et docker exec app sh /tmp/app/lab-check affiche PASS ou FAIL pour quatre points. Le lien du lab, Corner Shop search page, ouvre le formulaire de recherche dans un onglet.
Que demander aux élèves de rendre
La sortie de l’attaque avant la correction et après, et celle de docker exec app sh /tmp/app/lab-check à la fin, pour que le changement soit visible dans le terminal de l’élève. Puis la ligne qu’ils ont modifiée et une phrase de leurs mots sur la raison pour laquelle la nouvelle ligne ne peut pas être injectée, sur ce qu’un attaquant aurait pu faire avec l’ancienne, et sur ce qui aiderait encore (le compte avec lequel l’application se connecte, des mots de passe jamais stockés en clair). Le contrôle dit si la boutique se comporte comme il faut ; seule l’explication dit si cela a été compris.
Le contrôle est celui du lab : lab-check interroge la boutique en marche à sa propre adresse, il indique donc ce que fait la boutique et non ce que dit un fichier, et il se termine par un succès uniquement si les quatre lignes passent. Rien n’est noté automatiquement. Ces labs sont souvent utilisés avec des élèves de 16 et 17 ans : une copie est privée à l’élève, un membre du personnel qui enseigne le module peut l’ouvrir, et l’ouverture du travail d’un élève est inscrite dans le journal d’accès, que l’élève peut lire.
Une leçon de base sur ce lab
SQL Injection Fix Basics est une petite leçon qui se fait dans ce lab, chaque étape étant expliquée et accompagnée d’un bouton Exécuter qui tape sa commande dans le terminal de l’élève. Elle commence par la règle unique, cherche dans la boutique, lui fait afficher tous les produits, corrige la ligne avec une commande, redémarre la boutique et l’attaque de nouveau, puis lance le contrôle. Lire le code et taper la correction à la main sont laissés à l’élève.
Un compte personnel gratuit la reçoit dans le module Basics, qui se trouve sur « Accueil », chaque établissement peut la copier depuis le dossier Basics de la Bibliothèque, et un nouvel établissement l’a dans un module appelé Lab Basics (Sample). Elle est volontairement petite : elle montre à un enseignant ce qu’est une leçon qui se fait dans un lab, et le lab fait le reste. Copiez-la dans un module à vous pour la modifier.
Le code sur GitHub
Le fichier compose lance l’image officielle de Python, figée sur une version, comme seul service, et écrit le programme de la boutique au démarrage. Python est sous licence de la Python Software Foundation et n’est pas distribué par nous. Le test du dépôt fait passer un élève par l’attaque, la correction, un arrêt et un redémarrage, puis un retour au départ, sous les mêmes limites que celles de la plateforme.
En faire un travail
Indiquez dans la tâche quoi attaquer, quelle ligne corriger et ce qu’il faut rendre.
- Créer le lab. Dans votre module, ajoutez une tâche et choisissez la carte « Lab de conteneurs », puis « Dans un dépôt GitHub ». Indiquez https://github.com/mitsurutech/lab-sqli-fix avec la branche main. Le fichier compose par défaut est compose.yaml. Faites d’abord un fork du dépôt si vous voulez le modifier.
- Publier et l’essayer. « Publier » fige le commit qui vous a été montré : un changement ultérieur dans le dépôt ne modifie donc pas un lab que vous avez déjà proposé. Démarrez d’abord votre propre copie.
- Le distribuer. Attribuez-le comme n’importe quelle tâche, avec une échéance si vous le souhaitez, et indiquez dans la tâche ce qu’il faut faire et ce qu’il faut rendre.
- Noter ce qui est rendu. Ouvrez la copie d’un élève et le travail rendu, notez-le et renvoyez-le avec un motif s’il demande un complément.
Questions fréquentes
- Que se passe-t-il si un élève enregistre une erreur dans le programme ?
- Le lab démarre quand même. Un programme qui ne compile pas au démarrage est conservé à côté sous le nom app.py.broken et le programme faible est réécrit. Pour repartir volontairement du programme faible, lancez docker exec app rm /tmp/app/app.py puis docker restart app.
- Y a-t-il une partie sur les comptes et les privilèges de la base de données ?
- Non. La boutique utilise SQLite, qui n’a pas de comptes auxquels accorder des droits, et un lab n’a pas d’internet pour installer un client de serveur de base de données. Le moindre privilège est un bon sujet à demander dans l’explication écrite.
- L’élève doit-il installer quelque chose ou atteindre internet ?
- Non. Python et curl sont dans les images du lab, le terminal est dans le navigateur, et la copie du lab n’a aucune sortie vers internet.