Mittwoch, 23. November 2011


Topthema

Donnerstag, 18. September 2008 | Topthema

About Security #173: Schwachstellen-Suche: SQL-Injection mit Escape

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/045201)
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share

Zur Verhinderung von SQL-Injection gibt es außer dem in About Security #172 beschriebenen Ausfiltern unerwünschter Eingaben auch die Möglichkeit, Sonderzeichen wie z.B. das einfache Anführungszeichen ' zu escapen (maskieren). Danach werden sie von der Datenbank als Teil der Eingabe erkannt und können nicht zum Beenden eines vorhandenen Ausdrucks verwendet werden. Wieso das nicht zwingend zum gewünschten Erfolg führt, erfahren Sie in dieser Folge.

Security aktuell
T�glich aktuelle Security-Infos!

Escape statt Löschen

Wie bereits in About Security #167 beschrieben wurde, werden zwei einfache Anführungszeichen zusammen als Escape-Sequenz interpretiert: Sie ergeben ein einfaches Anführungszeichen, das als Bestandteil eines Strings und nicht als dessen Abschluss betrachtet wird. Möchte man z.B. O'Reilly in einer SQL-Abfrage verwenden, muss das ' escaped werden: O''Reilly. Viele Entwickler sind der Ansicht, durch das Verdoppeln jedes in einer Benutzereingabe enthaltenen einfachen Anführungszeichen könne SQL-Injection verhindert werden. Zum einen verhindert das aber nur SQL-Injection-Angriffe, die auf das Einschleusen von '-Zeichen angewiesen sind, z.B. um einen String zu beenden, um dann dahinter eigenen Code anzufügen. Zum anderen können beim Einsatz weiterer Filter diese unter Umständen so kombiniert werden, dass das Escapen aufgehoben wird.

Als Beispiel soll wieder die Authentifizierung aus About Security #167 dienen:

SELECT * FROM Benutzer WHERE Benutzername = '$name' AND Passwort = '$pass'

Als Schutzmaßnahmen gegen SQL-Injection werden alle einzelnen Anführungszeichen in der Eingabe verdoppelt, außerdem wird die Länge der Eingabe auf 10 Zeichen begrenzt - alles danach wird abgeschnitten.

Bei der Eingabe von

admin'--

als Benutzername und einem beliebigen Passwort ergibt das

SELECT * FROM Benutzer WHERE Benutzername = 'admin''--' AND Passwort = 'nix'

Diese Abfrage schlägt fehl, ein Umgehen der Authentifizierung ist also nicht möglich. Aber wie sieht es bei der Eingabe von z.B.

abcdefghi'

aus (bzw. allgemein bei der Eingabe von 9 Zeichen, gefolgt von einem Anführungszeichen)? Die Webanwendung verdoppelt das Anführungszeichen und erhält

abcdefghi''

Danach wird die Eingabe nach 10 Zeichen abgeschnitten - zurück bleibt die vorherige Eingabe, die zu folgender SQL-Abfrage führt:


SELECT * FROM Benutzer WHERE Benutzername = 'abcdefghi'' AND Passwort = 'nix'

Das doppelte Anführungszeichen hinter dem i wird als Teil des blau markierten Strings interpretiert. Das nutzt dem Angreifer auf den ersten Blick wenig, denn auch damit kann die Authentifizierung nicht umgangen werden. Wird aber zusätzlich als Wert für das Passwort

 or 1=1--

eingegeben, ergibt das folgende Abfrage:


SELECT * FROM Benutzer WHERE Benutzername = 'abcdefghi'' AND Passwort = ' or 1=1--'

Gesucht wird nach Zeilen, in denen in der Spalte Benutzername

abcdefghi'' AND Passwort = 

steht oder für die 1=1 gilt. Da 1=1 immer erfüllt ist, wird die Authentifizierung so umgangen.

Werden verschiedene Funktionen kombiniert, muss immer mit Nebenwirkungen gerechnet werden. Ganz besonders gilt das natürlich bei Schutzfunktionen, bei denen besonders darauf geachtet werden muss, das sie sich nicht gegenseitig aufheben.

SQL Column Truncation

Das oben beschriebene Problem kann leicht mit einer von Stefan Esser als 'SQL Column Truncation' bezeichneten Schwachstelle verwechselt werden. Deren Ursache ist eine fehlende Längenprüfung durch die Webanwendung: Überlange Eingaben werden beim Einfügen in die Datenbanktabelle von der Datenbank gekürzt, ohne das die Webanwendung das berücksichtigt. MySQL kürzt zu lange Eingaben, und gibt im Normalfall nur eine Warnung aus. Warnungen erreichen die Webanwendung aber i.A. nicht oder werden von ihr nicht berücksichtigt.

About Security: Die komplette Serie

Als Beispiel nennt Stefan Esser ein Formular zur Anmeldung neuer Benutzer. Der Benutzername des Administrators ist bekannt, z.B. 'admin'. Es wird MySQL in der Default-Konfiguration verwendet, die Webanwendung prüft die Länge der Eingaben nicht und die Spalte für die Benutzernamen nimmt nur bis zu 16 Zeichen lang Namen auf.

Versucht ein Angreifer, sich als 'admin ' zu registrieren, schlägt das fehl. Beim Vergleich des neuen Benutzernamens mit den vorhandenen durch die Abfrage

SELECT * FROM user WHERE username='admin '

werden angehängte Leerzeichen ignoriert, so dass 'admin ' identisch mit 'admin' ist, die Webanwendung verweigert daher die Registrierung. Meldet sich der Angreifer aber mit dem Benutzernamen 'admin           x' an, wird dieser Benutzername nicht gefunden: Die Eingabe ist 17 Zeichen lang, die Spalte für den Benutzernamen nimmt aber nur 16 Zeichen auf. Die Webanwendung akzeptiert diesen Benutzernamen daher und trägt ihn zusammen mit dem zugehörigen Passwort in die Datenbank ein. Da der Name aber für die Spalte zu lang ist, wird er von MySQL gekürzt und 'admin           ' eingetragen. Die Benutzertabelle enthält nun zwei Benutzernamen, die sich nur durch angehängte Leerzeichen unterscheiden. Je nachdem, wie die Webanwendung die Benutzernamen verwendet, kann das zu Problemen führen.

In der nächsten Folge werden einige weitere SQL-Injection-Angriffe beschrieben.

Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!

Carsten Eilers

About Security - Übersicht zum aktuellen Thema:

Kommentare

Folgende Links könnten Sie auch interessieren