SQL-Injection-Lab: eine schwache Shop-Suche angreifen, die Abfrage reparieren und die Reparatur belegen

Dieses Lab gibt jeder lernenden Person einen kleinen Shop mit einer Produktsuche, die für SQL-Injection anfällig ist. Die lernende Person greift sie vom Terminal des Labs aus mit curl an, bringt die Suche dazu, Produkte anzuzeigen, die nicht zum Verkauf stehen, sowie Benutzer und Passwörter des Shops, und repariert dann den Code im laufenden Container, sodass die Abfrage parametrisiert ist, startet den Shop neu und sieht, dass dieselben Angriffe nichts mehr finden, während normale Suchen weiter funktionieren.

Das Lab haben wir allein auf Basis des öffentlichen Python-Images entworfen, es gibt also keine fremde Anwendung anzugreifen: nur ein kurzes Programm von uns, das mit Absicht falsch ist. Es gilt die übliche Regel für ein Angriffs-Lab: Greifen Sie Ihre eigene Kopie an und sonst nichts. Die Kopie hat keine Verbindung zum Internet und keine zu anderen Lernenden, und man darf nie ein Werkzeug auf eine Website richten, die man nicht selbst besitzt.

Was Lernende hier lernen

Wie SQL-Injection entsteht: Ein Programm fügt das, was eine Besucherin oder ein Besucher eingetippt hat, in den Text seiner Datenbankanfrage ein, sodass ein Anführungszeichen die Anfrage vorzeitig beendet und der Rest von der besuchenden Person geschrieben wird. Die Lernenden brechen mit einem immer wahren OR aus der Anfrage aus, lesen mit einem UNION eine andere Tabelle, finden die verantwortliche Zeile und ersetzen sie durch eine parametrisierte Abfrage, die Anfrage und Wert getrennt sendet, sodass ein Wert nie Teil der Anfrage sein kann. Sie prüfen auch, dass die Reparatur die normale Nutzung nicht kaputt gemacht hat, wozu ein Produkt gehört, dessen Name ein Anführungszeichen enthält. Das Lab passt zu Einheiten über sicheres Programmieren und Websicherheit, und zur rechtlichen Seite davon: Befugnis und Geltungsbereich. Prüfen Sie den genauen Wortlaut in der Einheit Ihrer eigenen Prüfungsorganisation.

Im Browser ausführen

Der Shop ist der Dienst namens app, und das Terminal des Labs erreicht ihn unter diesem Namen. Ein docker-Befehl im Terminal kann den Dienst des Labs ansehen, betreten, neu starten und dessen Logs lesen: Er kann nichts erstellen, herunterladen oder entfernen. Das Programm liegt in einem benannten Volume, sodass das, was die lernende Person speichert, nach dem Stoppen und erneuten Starten des Labs noch da ist.

  1. Container-Seite öffnen. Wählen Sie in der Leiste „Entwickeln“ und dann „Einen Container ausführen“. Die Seite kann jeder öffnen, und das Git-Lab und das SQL-Lab starten ohne Konto. Jedes andere Lab braucht ein kostenloses Konto: Erstellen Sie eines, melden Sie sich an und wählen Sie dann „Starten“.
  2. Lab finden. Die Karte „Beispiel-Labs“ listet alle Beispiele auf. Suchen Sie „SQL-Injection: finden und beheben“.
  3. „Starten“ wählen. „Starten“ führt das Lab unverändert mit einem Klick aus. „Zuerst die Datei bearbeiten“ öffnet die Compose-Datei, damit Sie sie vor dem Start ändern können.
  4. Öffnen. Öffnen Sie auf der Seite des Labs das Terminal neben dem Lab. Führen Sie curl -s -G --data-urlencode "q=pen" http://app:8000/search aus, um den Shop zu durchsuchen, und bringen Sie ihn dann mit einer Suche nach x' OR 1=1 -- dazu, zu viel anzuzeigen. docker exec -it app vi /tmp/app/app.py öffnet das Programm zum Bearbeiten, docker restart app führt die neue Version aus, und docker exec app sh /tmp/app/lab-check gibt für vier Dinge PASS oder FAIL aus. Der Link des Labs, Corner Shop search page, öffnet das Suchformular in einem Tab.

Was Lernende abgeben sollten

Die Ausgabe des Angriffs vor der Reparatur und danach sowie von docker exec app sh /tmp/app/lab-check am Ende, sodass die Änderung im eigenen Terminal der lernenden Person sichtbar ist. Dazu die Zeile, die sie geändert hat, und ein Satz in eigenen Worten, warum die neue Zeile sich nicht einschleusen lässt, was eine angreifende Person mit der alten hätte tun können und was sonst noch helfen würde (das Konto, mit dem sich die Anwendung verbindet, Passwörter, die nie im Klartext gespeichert werden). Die Prüfung sagt, ob sich der Shop richtig verhält; nur die Erklärung sagt, ob es verstanden wurde.

Die Prüfung gehört zum Lab: lab-check fragt den laufenden Shop unter dessen eigener Adresse, es meldet also, was der Shop tut, und nicht, was eine Datei sagt, und es endet nur dann erfolgreich, wenn alle vier Zeilen bestehen. Nichts wird automatisch bewertet. Diese Labs werden oft mit 16- und 17-Jährigen genutzt: Eine Kopie ist für die lernende Person privat, eine Lehrkraft des Moduls kann sie öffnen, und das Öffnen der Arbeit einer lernenden Person wird im Zugriffsprotokoll festgehalten, das diese einsehen kann.

Eine Grundlagenlektion zu diesem Lab

SQL Injection Fix Basics ist eine kleine Lektion, die in diesem Lab durchgearbeitet wird, wobei jeder Schritt erklärt wird und eine Schaltfläche „Ausführen“ seinen Befehl im Terminal der lernenden Person eintippt. Sie beginnt mit der einen Regel, durchsucht den Shop, bringt ihn dazu, jedes Produkt anzuzeigen, repariert die Zeile mit einem Befehl, startet den Shop neu und greift ihn erneut an und führt dann die Prüfung aus. Den Code zu lesen und die Reparatur von Hand einzutippen bleibt der lernenden Person überlassen.

Ein kostenloses persönliches Konto erhält sie im Modul „Basics“ auf der Startseite, jede Einrichtung kann sie aus dem Ordner „Basics“ der Bibliothek kopieren, und eine neue Einrichtung startet mit ihr in einem Modul namens Lab Basics (Sample). Sie ist bewusst klein: Sie zeigt einer Lehrkraft, was eine in einem Lab durchgearbeitete Lektion ist, und das Lab erledigt den Rest. Kopieren Sie sie in ein eigenes Modul, um sie zu ändern.

Der Code auf GitHub

Die Compose-Datei führt das offizielle Python-Image, auf eine Version festgelegt, als einzigen Dienst aus und schreibt beim Start das Programm des Shops. Python steht unter der Lizenz der Python Software Foundation und wird von uns nicht verteilt. Der Test des Repositorys spielt eine lernende Person durch den Angriff, die Reparatur, einen Stopp und einen Start und einen erneuten Start, unter denselben Grenzen, die die Plattform anwendet.

Als Arbeit stellen

Beschreiben Sie in der Aufgabe, was anzugreifen ist, welche Zeile zu reparieren ist und was abzugeben ist.

  1. Lab erstellen. Fügen Sie in Ihrem Modul eine Aufgabe hinzu und wählen Sie die Karte „Container-Lab“, dann „In einem GitHub-Repository“. Geben Sie https://github.com/mitsurutech/lab-sqli-fix mit dem Branch main an. Die Compose-Datei ist standardmäßig compose.yaml. Forken Sie das Repository zuerst, wenn Sie sie ändern möchten.
  2. Veröffentlichen und ausprobieren. „Veröffentlichen“ legt den Commit fest, der Ihnen gezeigt wurde, sodass eine spätere Änderung im Repository ein bereits gestelltes Lab nicht verändert. Starten Sie zuerst Ihre eigene Kopie.
  3. Zuweisen. Weisen Sie es wie jede Aufgabe zu, auf Wunsch mit einem Fälligkeitsdatum, und beschreiben Sie in der Aufgabe, was zu tun ist und was abgegeben werden soll.
  4. Abgaben bewerten. Öffnen Sie die Kopie einer lernenden Person und ihre Abgabe, bewerten Sie sie und geben Sie sie mit einer Begründung zur Überarbeitung zurück, wenn mehr nötig ist.

Häufige Fragen

Was ist, wenn eine lernende Person einen Fehler im Programm speichert?
Das Lab startet trotzdem. Ein Programm, das beim Start des Labs nicht kompiliert, wird daneben als app.py.broken aufbewahrt, und das schwache wird neu geschrieben. Um absichtlich mit dem schwachen Programm zu beginnen, führen Sie docker exec app rm /tmp/app/app.py und dann docker restart app aus.
Gibt es einen Teil über Datenbankkonten und Berechtigungen?
Nein. Der Shop nutzt SQLite, das keine Konten kennt, denen man etwas zuweisen könnte, und ein Lab hat kein Internet, aus dem sich ein Client für einen Datenbankserver installieren ließe. Das Prinzip der minimalen Rechte ist ein gutes Thema für die schriftliche Erklärung.
Muss die lernende Person etwas installieren oder ins Internet kommen?
Nein. Python und curl sind in den eigenen Images des Labs, das Terminal läuft im Browser, und die Lab-Kopie hat keinen Weg ins Internet.