Expedition ins Neuland. Heute: Das Problem mit Spritzen und deinem Passwort.
Heute nehme ich dich mit auf eine kleine Expedition ins #Neuland. Wir werden erfahren, was Spritzen und dein Passwort miteinander zu tun haben und was Webseitenbetreiberinnen dagegen tun.

Das Neuland
Am 29. Oktober 1969 begann die Erfolgsgeschichte des Internets, heute auch bekannt als #Neuland. Damals waren es zwei Großcomputer, verbunden über Telefonleitungen. Zwei Jahre später waren es bereits 15 Computer, die so miteinander kommunizieren konnten. Das, was wir heute Internet nennen, das World Wide Web, kurz www, wurde allerdings erst 1991 im Forschungszentrum CERN entwickelt. Ein Meilenstein, der maßgeblich noch heute unseren Umgang mit dem Internet prägt. Das Konzept von Webseiten und Webbrowsern (wie diese, die du über deinen Browser gerade betrachtest), wurde damals erfunden.1
Obwohl die maßgeblichen Technologien damals bereits ihre Anfänge nahmen, ist das Internet bis heute in weiten Teilen der Bevölkerung nach wie vor #Neuland. Viele können es gerade so benutzen, aber vom Verstehen sind die meisten auch jungen Leute meilenweit entfernt. Ich möchte in dieser Serie auf meinem Blog einzelne spannende Teile des #Neuland zu beleuchten und dir einfach und verständlich näherbringen.

Browser? Ist das nicht der Bösewicht aus der Mario-Reihe?
Fast zumindest. Eine Webseite ist im einfachsten Fall ein Textdokument. Probier es einfach mal aus. Einfach Rechtsklick auf deinen Desktop (Das Ding mit hübschem Bild und einem Haufen an Symbolen darauf bei deinem PC), dann mit dem Mauszeiger auf „Neu“ gleiten und dann in der Liste „Textdokument“ auswählen. Du solltest jetzt eine neue Datei auf deinem Bildschirm haben, die „Neues Textdokument.txt“ heißt. Jetzt klick jetzt doppelt auf die Datei. Es sollte sich der Editor öffnen. Füge dort folgenden Text ein:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Titel</title>
</head>
<body>
<div>Hallo, ich bin deine erste eigene Webseite!</div>
</body>
</html>
Nachfolgen siehst du den Code in einem Editor. Spiel ruhig mal damit rum!
Nun speichre die Datei ab. Jetzt müssen wir die Datei noch umbenennen. Rechtsklick dazu einfach mal auf die Datei und wähle „Umbenennen“. Du musst jetzt das „.txt“ durch „.html“ ersetzten. Es wird eine Meldung kommen, die sagt, dass damit die Datei möglicherweise unbrauchbar wird. Die kannst du mit „Ja“ bestätigen. Du wirst sehen, dass sich das Symbol der Datei geändert hat. Mit einem Doppelklick auf die Datei kannst du diese jetzt öffnen.
Herzlichen Glückwunsch! Du hast soeben deine erste eigene Webseite programmiert. Würdest du diese Datei über einen Server bereitstellen, zum Beispiel unter der Adresse: dersimoezdag.de, dann könnte jeder diese Datei ebenfalls in seinem Browser betrachten.
Aber wo kommen jetzt deine Blogbeiträge her?
Nun, deine Webseite ist noch etwas leer. Du kannst jetzt natürlich viele solcher Dateien anlegen, in jede statt meinem Beispieltext einen Blogbeitrag schreiben und die dann über einen Server bereitstellen. Früher machte man das tatsächlich, aber heutzutage verwendet man dafür eine Datenbank. Dabei braucht man keine einzelne Datei mehr für einen Beitrag, sondern aus einer Art Tabelle sucht der Server nur den richtigen Inhalt für den abgerufenen Blogbeitrag raus und fügt den einfach ein.
Das läuft folgendermaßen: Du gibst die Adresse zu einem Beitrag an. Zu Vereinfachung sagen wir mal, dass die Adresse genau der Name des Beitrags ist. Das löst eine Anfrage bei meinem Server aus mit dem Inhalt „Gib mir bitte den Beitrag namens X“. Mein Server schickt dann eine Anfrage an die Datenbank „Gibt es einen Beitrag mit Namen X, der veröffentlicht ist?“. Die Datenbank sucht dann und antwortet entweder mit allem, was sie gefunden hat oder sagt, dass es leider keinen solchen Beitrag gibt. Mein Server fügt dann in eine Datei den Beitrag ein oder schreibt rein, dass der Beitrag nicht gefunden wurde und schickt dir die Datei zurück. Die Sprache, in der Server und Datenbank kommunizieren ist oft SQL.
SQWas?
SQL. „Structured Query Language“ übersetzt „Strukturierte Abfrage-Sprache“ stellt eine Möglichkeit dar, mit der Ich von meinem Server Informationen holen kann, die ich dir dann als beispielsweise Blogbeitrag anzeigen kann. Ich habe also auf dem Server eine riesige Tabelle. In der linken Spalte steht zum Beispiel immer der Name des Beitrags, in der Mittleren, ob der Beitrag veröffentlicht wurde oder nicht und in der rechten Spalte der Text des Betrags.
Nun möchtest du unbedingt nochmal meinen Beitrag „Luca: Coronabekämpfung auf dem Holzweg“ lesen. Du klickst also auf den Link und mein Server sagt jetzt meiner Datenbank, dass sie in der Tabelle nach der Zeile, in der der Beitrag gespeichert ist, suchen soll. Das sieht ungefähr so aus:
Server an Datenbank:
Gib mir den Inhalt der Zeile, in der NAME = "Luca: Coronabekämpfung auf dem Holzweg" ist
und VERÖFFENTLICHT = "ja" ist.
Meine Datenbank gibt dann den Blogbeitragstext als Antwort. Dieser wird dann von meinem Server in die Datei eingefügt und die Datei mit dem Text dann an deinen Browser geschickt.
Du hast mir Spritzen versprochen!!! Wo sind die jetzt?
Du willst aber sicher auch wissen, welche Blogbeiträge ich noch nicht veröffentlicht habe, oder? Nun, die Abfrage an den Server ist natürlich nicht starr. Vielmehr muss ich in die Abfrage einfügen, welchen Blogbeitrag die Nutzerin angefragt hat. Hierfür nutze ich eine Art blanko-Abfrage, in die ich einfach den gewünschten Beitrag einfüge.
Server an Datenbank: Gib mir den Inhalt der Zeile, in der NAME = "{HIER NUTZERINNENANFRAGE EINFÜGEN}" ist und VERÖFFENTLICHT = "ja" ist.
Das ist übrigens tatsächlich so und ein häufiges Einfallstor für Hackerinnen. So wird zum Beispiel bei der Eingabe von Nutzerinnennamen und Passwort irgendwann daraus genauso eine Abfrage gebaut, um zu sehen, ob es eine entsprechende Nutzerin mit entsprechendem Passwort gibt.
Server an Datenbank: Gib mir den Inhalt der Zeile, in der NUTZERINNENNAME = "{HIER NUTZERINNENNAME EINFÜGEN}" ist und PASSWORT = "{PASSWORT}" ist.
Die Abfrage würde also nur etwas zurückgeben, wenn eine Nutzerin mit genau dem eingegebenen Passwort existiert. Genau so kann ich aber auch sagen, dass mir von einem Feld der Inhalt egal ist durch ein * oder statt einem „und“ auch ein „oder“ einsetzten, um eine Voraussetzung für einen Treffer in der Tabelle alternativ zu gestalten. Ich kann der Datenbank also logisch verknüpfte Anweisungen geben.
Du kannst jetzt im Prinzip jeden beliebigen Eintrag abrufen, der veröffentlicht ist, indem du einfach jeden beliebigen Namen mal ausprobierst, bis du einen Treffer hast. Du kannst aber auch mit etwas Kreativität jeden unveröffentlichten Abrufen. Der Grund ist folgender: Die Abfrage ist tatsächlich einfach ein Text, wie er hier steht, der an die Datenbank gesendet wird. Der Text wird dann von der Datenbank einfach gelesen und ganz stur ausgeführt. Wir müssen also nur in diesen Text etwas „spritzen“, damit die Datenbank uns mehr Einträge zurückschickt als vorgesehen.
Der Ablauf ist also folgender: Nutzerin gibt ein, welchen Blogbeitrag sie sehen will. Dann wird in der oben gezeigten blanko-Abfrage der Teil {HIER NUTZERINNENANFRAGE EINFÜGEN} durch die eingegebene Zeichenfolge ersetzt.
Hierzu nutzen wir es aus, dass die Abfrage am Ende tatsächlich nur ein reiner Text ist. Eine Art SMS, die wir der Datenbank schicken mit der Bitte um Antwort. Wir fügen einfach in die Abfrage in paar mehr Zeichen ein, in dem wir die Nutzerinnenanfrage etwas erweitern.
{HIER NUTZERINNENANFRAGE EINFÜGEN} füllen wir jetzt mit folgendem:
*" ist und VERÖFFENTLICHT = "nein" ist oder NAME = "*
Du fragst dich, was das soll? Nun, fügen wir den Text mal zusammen, in dem wir die Nutzerinnenanfrage ganz normal einfügen:
Server an Datenbank: Gib mir den Inhalt der Zeile, in der NAME = "*" ist und VERÖFFENTLICHT = "nein" ist oder NAME = "*" ist und VERÖFFENTLICHT = "ja" ist.
Da staunst du, was? Plötzlich haben wir eine ganz andere Abfrage, einfach, weil wir in das entsprechende Feld ein paar Anführungszeichen und entsprechende Befehle (im Beispiel unterstrichen) gesetzt haben. Wenn wir der Logik folgen, dann soll jetzt die Datenbank alles zurückliefern, egal welchen Namen der Beitrag hat und egal, ob veröffentlicht oder nicht. Die Datenbank ist „dumm“. Sie weiß nicht, was eigentlich gewollt war, sondern befolgt stur jeden Befehl, mit dem man sie füttert.
Plötzlich würde die Datenbank mir also alle Beiträge liefern, die egal welchen Namen haben und veröffentlicht sind oder egal welchen Namen haben und unveröffentlicht sind. Kurz gesagt: Alle Beiträge würden ausgespielt werden, auch die, die ich noch für mich behalten möchte. Genau das nennt man SQL-Injection. Also einschleusen von Befehlen in die regulären Anfragen an die Datenbank, die nicht vorgesehen wurden.
Keine Sorge!
Wir Entwicklerinnen wissen das natürlich und haben da so unsere Tricks, um das zu verhindern. Wir können zum Beispiel die Nutzerinnenanfrage überprüfen, ob die in unserem Beispiel Anführungszeichen enthält, oder wir können die Antwort der Datenbank nochmal filtern, ob da etwa Elemente dabei sind, die noch nicht veröffentlicht sind. Aber trotzdem ist es eine sehr häufig angewandte Technik und vor allem eine, die sehr einfach ist, denn sie nutzt die ganz normalen Abfragetechniken der Webseite aus. Es bedarf also keiner Lücke im System, sondern unsauberes Arbeiten bei der Verarbeitung der Nutzerinnenanfragen reicht aus, um hier eine Schwachstelle zu schaffen.
Trotzdem wurde mit dieser Technik durch geschicktes ausnutzen von solchen Abfragen schon so manches Passwort gestohlen. Das Wissen um diese Gefahren ist also für alle Entwicklerinnen äußerst wichtig.
Ich hoffe, dass der Beitrag nicht zu technisch war und dir einen kleinen Einblick ins #Neuland gegeben hat. Nutze auch gerne das Kontaktformular für Feedback!
Quellen:
- https://www.spiegel.de/netzwelt/web/internet-wird-50-wie-alles-mit-zwei-buchstaben-und-einem-absturz-anfing-a-1293668.html
P.S. In diesem Beitrag habe ich das generische Femininum verwendet. Ich hoffe, die Männer, die den Beitrag lesen, fühlen sich genauso mitgemeint, wie es die Frauen sich schon immer beim generischen Maskulinum fühlen sollen.