SQL Injections in Webanwendungen

Werbung
SQL Injections in Webanwendungen
Maximilian Geissler
Betreuer: Daniel Raumer
Seminar Network Hacking WS2013
Lehrstuhl Netzarchitekturen und Netzdienste
Fakultät für Informatik, Technische Universität München
Email: [email protected]
KURZFASSUNG
3.
Die meisten Webanwendungen sind verwundbar gegenüber
SQL Injections. Dieses Paper gibt einen Überblick über SQL
Injections und Gegenmaßnahmen. Dazu wird die Funktionsweise von SQL Injections erläutert. Auf die im Bereich der
HTTP Webanwendungen häufig anzutreffende Kombination PHP und MySQL wird besonders eingegangen. Durch
die vorgestellten Prinzipien können typische Fehler bei der
Entwicklung von Webanwendungen vermieden und SQL Injections verhindert werden.
Es gibt unterschiedliche Motivationen für einen Angreifer,
eine SQL Injection durchzuführen. In dieser Arbeit werden
diese folgendermaßen klassifiziert:
Schlüsselworte
Manipulation von Daten
Durch das Hinzufügen, Veränderen oder Löschen von
Daten kann ein Angreifer eine Anwendung manipulieren. Beispielsweise könnte er in einem Webshop den
Preis für eine bestimmte Ware verändern.
SQL Injection, SQLIA, SQLIV, Webanwendung
1.
EINFÜHRUNG
SQL Injections sind eine weit verbreitete Methode, Anwendungen anzugreifen. Die meisten Webanwendungen [1] und
auch lokale Anwendungen, die auf einer SQL-Datenbank aufbauen, sind davon betroffen. Datenbanken sind ein beliebtes
Angriffsziel, da darin wertvolle Inhalte, wie z.B. Kundendaten einer Firma, verwaltet werden. Es existieren sehr viele
Webanwendungen, die gegenüber SQL Injections verwundbar sind [2]. Aus diesen Gründen sind SQL Injections weit
verbreitet. Laut dem Application Vulnerability Trends Re”
port 2013“ [3] der Cenzic, Inc waren durchschnittlich 6%
aller getesteten Anwendungen verwundbar gegenüber SQL
Injections. Das OWASP Top Ten Project [4] stuft für das
Jahr 2013 SQL Injections als die größte Gefahr für Webanwendungen ein [5].
Im folgenden Abschnitt 2 wird die Definition einer SQL Injection angegeben und in Abschnitt 3 werden die Ziele eines
Angriffs vorgestellt. Anschließend werden in Abschnitt 4 die
Angriffspunkte als Basis für die Durchführung einer SQL
Injection (Abschnitt 5) aufgezeigt. In Abschnitt 6 werden
Maßnahmen gegen SQL Injections vorgestellt.
2.
DEFINITION EINER SQL INJECTION
SQL Injection bezeichnet einen Angriff, auch SQL injection attack (SQLIA) genannt, auf datenbankbasierende Anwendungen durch spezielle Benutzereingaben. Diese Benutzereingaben werden aufgrund mangelhafter Überprüfung akzeptiert und erlauben dem Angreifer, Daten zu manipulieren
oder die Anwendung anderweitig zu kompromittieren [6].
Die Vorraussetzung einer SQL Injection ist eine SQLIV (SQL
injection vulnerability), also eine Sicherheitslücke oder Schwachstelle in einer Anwendung.
ZIELE VON SQL INJECTIONS
Kopieren von Daten
Das gängigste Ziel einer SQL Injection ist es, Daten,
die nicht öffentlich verfügbar sind, einzusehen und zu
kopieren [7]. Der Angreifer verschafft sich so wertvolle
Informationen.
Denial of Service (DoS)
Bei einem Denial of Service ist die Anwendung für Benutzer nicht mehr verfügbar. Die Motivation hinter
einer DoS Attacke können wirtschaftliche Interessen
oder Konkurrenzkämpfe sein.
Umgehen von Authentifizierungen
Angreifer können sich durch SQL Injections Zugriff auf
Funktionen von Anwendungen verschaffen, die durch
Authentifizierungen geschützt sind.
Einschleusen von Code
Wenn ein Angreifer in ein System eingedrungen ist,
kann er schädlichen Code einschleusen1 , den er später
ausführen kann.
Oft verfolgen Angreifer nicht nur eines sondern mehrere dieser Ziele.
4.
ANGRIFFSPUNKTE
Die typischen Angriffspunkte bei datenbankbasierten
Webanwendungen, die mittels HTTP mit dem Server kommunizieren, sind:
Benutzereingaben
Benutzereingaben können in Webanwendungen unter
Verwendung von HTML Formularen an die Anwendung übermittelt werden. Durch den Missbrauch dieser Formulare wird eine SQL Injection möglich. Dabei wird ein spezieller Text in ein Feld des Formulares
1
Beispielsweise mit Stored Procedures [8].
5.1.1
Angriffspunkte finden
Zunächst müssen Angriffspunkte, wie in Abschnitt 4 beschrieben, gefunden werden. Sie bilden die Basis für die weiteren Schritte.
5.1.2
Fingerprinting
Verschiedene Datenbanksysteme reagieren leicht unterschiedlich auf bestimmte Eingaben. Fehlerhafte Eingaben können
zu Fehlermeldungen führen, die viele Informationen verraten
(siehe auch Abschnitt 5.2.2). Falls es gelingt, durch dieses
Fingerprinting auf Typ und Version zu schließen, kann ein
gezielter Angriff auf dieses Datenbanksystem durchgeführt
werden [10].
Abbildung 1: Missbrauch von Formularen
eingegeben, wie in Abbildung 1 dargestellt. Wenn die
Clientsoftware auf HTML und Scriptsprachen wie Javascript aufbaut, liegt sie nicht in kompilierter Form,
sondern als Quelltext vor. Somit ist sie leicht zu verändern. Einige Browser bieten die Möglichkeit, mit Hilfe
von Developer Tools den HTML Code einer Webseite
direkt zu verändern und somit Validierungen, die in
Skriptsprachen implementiert sind, zu umgehen. Beispielsweise bietet der Browser Firefox eine solche Funktion im Menü unter Tools/Web Developer/Inspector.
HTTP Header
Eine weitere Möglichkeit, eine Webanwendung anzugreifen, sind HTTP Header. Wenn die Daten dieser
Header in Datenbankabfragen verwendet werden, kann
durch veränderte Header eine SQL Injection durchgeführt werden.
Cookies
Cookies sind ein wichtiger Angriffspunkt für Webanwendungen. Da sie auf Seite des Clients gespeichert
sind, ist eine Manipulation möglich. Cookies werden
als HTTP Header übertragen und somit gilt für sie die
selbe Missbrauchsmöglichkeit wie für HTTP Header.
Parameter
Mithilfe der Methoden GET und POST können in
Webanwendungen Parameter in Form von Key-ValuePaaren an den Server übergeben werden. Diese Parameter können auf der Clientseite beliebig gesetzt werden. Für GET wird eine angepasste URL aufgerufen
und für POST wird ein modifizierter HTTP Request
abgesetzt.
5.
DURCHFÜHRUNG EINER SQLIA
In diesem Kapitel wird vorgestellt, wie ein Angriff vorbereitet werden kann und welche Angriffsarten möglich ist.
5.1
Angriffsvorbereitung
Um einen erfolgreichen und präzisen Angriff durchzuführen,
ist es hilfreich, Informationen über die Anwendung und deren Datenbank zu sammeln. Im Folgenden wird ein kurzer
Überblick über Techniken zum Erlangen dieser Informationen gegeben.
5.1.3
Datenbankschemata herausfinden
Kenntnisse über die Datenbankschemata werden gebraucht
für eine SQL Injection. Informationen wie Tabellennamen
und Spaltennamen sind nötig, um Datenbankabfragen zu erstellen, die die gesuchten Daten liefern [11].
5.1.4
Rechte erlangen
Wenn bestimmte Daten im Datenbanksystem durch besonders hohe Zugriffsrechte geschützt sind, kann ein Angreifer
versuchen, sich durch einen vorausgehenden Angriff höhere
Benutzerrechte zu verschaffen.
5.2
Angriffsarten
In diesem Abschnitt werden unterschiedliche Angriffsarten
vorgestellt, die in einer SQLIA genutzt werden können. Viele der Angriffe haben gemeinsam, dass in den SQL Abfragen mithilfe von Kommentarzeichen, wie z.B. - -“, Teile der
”
Abfrage für den SQL Interpreter unsichtbar gemacht werden [12].
5.2.1
Tautologien
Bei dieser Art von Attacke wird eine SQL Abfrage mit einer
WHERE Bedingung ausgenutzt. Die WHERE Bedingung
wird durch geschicktes Anpassen der Eingabe zu einer Tautologie umgebaut [7]. Ein typischer Anwendungsfall ist das
Umgehen von Authentifizierungen. Eine mögliche SQL Abfrage für das Formular aus Abbildung 1 ist in Listing 1 zu
sehen. Dabei werden die Platzhalter $u und $p durch den
Inhalt der Felder Username bzw. Password des Formulares
ersetzt.
Listing 1: SQL Abfrage
s e l e c t ∗ from u s e r s where username = ’ $u ’
and password = ’ $p ’
Listing 2: SQL Injection
hi ’ o r 1=1 −−
Wird nun statt einem Benutzernamen eine SQL Injection
wie in Listing 2 angegeben, ist die WHERE Bedingung der
SQL Abfrage in eine Tautologie umgebaut worden (Listing 3).
Listing 3: Modifizierte SQL Abfrage
s e l e c t ∗ from u s e r s where username = ’ h i ’
or 1=1 −− ’ and password = ’ t e x t ’
Das ist möglich durch das geschickte Verwenden der Steuerzeichen - -“, die den SQL Interpreter anweisen, den letzten
”
Teil der Abfrage als Kommentar zu interpretieren und folglich zu ignorieren (In Listing 3 kursiv dargestellt). Somit
liefert die resultierende SQL Abfrage alle Datensätze der
Tabelle users ohne Authentifizierung.
5.2.2
Ungültige Abfragen
Datenbanksysteme geben bei ungültigen SQL Abfragen Fehlermeldungen zurück, falls diese Funktion nicht deaktiviert
wurde. Wenn diese Fehlermeldungen dem Benutzer in der
Webanwendung angezeigt werden, können durch sie Informationen über das Datenbanksystem und die Datenbankstrukturen gesammelt werden. Diese Attacke dient vor allem der
Angriffsvorbereitung, weil mit Hilfe der neu gewonnenen Informationen präzisere Angriffe möglich werden.
Listing 4: SQL Abfrage
s e l e c t ∗ from s t u d e n t s where name = ’ $n ’
Listing 5: Modifizierte SQL Abfrage
s e l e c t ∗ from s t u d e n t s where name = ’
Die SQL Abfrage in Listing 4 wird durch die SQL
Injection -- im Platzhalter $n zu einer ungültigen SQL
Abfrage (Listing 5). Diese ungültige SQL Abfrage führt beispielsweise zu folgender Fehlermeldung:
You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server
version for the right syntax to use near ” at line 1
Wenn die Fehlermeldung in der Webanwendung angezeigt
wird, ist dem Angreifer nun bekannt, dass die Webanwendung MySQL als Datenbanksystem verwendet. Damit sind
ihm künftig gezielte Angriffe auf dieses Datenbanksystem
möglich. Der Angreifer hat somit erfolgreich Fingerprinting
(Abschnitt 5.1.2) betrieben. Auch über Datenbankstrukturen können Informationen gesammelt werden. Wenn der Name der Benutzertabelle nicht bekannt ist, kann ein Angreifer gängige Tabellennamen wie users, user, accounts usw.
durchprobieren. MySQL würde z.B. Fehlermeldungen wie
Table ’database.users’ doesn’t exist
liefern. Der Angreifer wiederholt seine Attacke mit anderen
Tabellennamen solange, bis der Fehler nicht mehr auftritt.
Dann ist ihm der richtige Tabellenname bekannt. Die gleiche
Vorgehensweise kann auch für unbekannte Spaltennamen in
Tabellen verwendet werden.
5.2.3
Union Queries
Mithilfe von UNION können in SQL die Ergebnisse mehrerer
Abfragen zusammengefasst werden. Auf dieser Basis werden
Union Query Angriffe durchgeführt.
Listing 6: SQL Abfrage
s e l e c t s e m e s t e r from s t u d e n t s
where name = ’ $n ’
Listing 7: SQL Injection
’ union s e l e c t accountNumber from
bankAccounts where u s e r i d = 42 −−
Der Platzhalter $n in Listing 6 wird ersetzt durch die SQL
Injection in Listing 7. Das Resultat ist dargestellt in Listing 8.
Listing 8: Modifizierte SQL Abfrage
s e l e c t s e m e s t e r from s t u d e n t s
where name = ’ ’
union s e l e c t accountNumber
from bankAccounts
where u s e r i d = 42 −− ’
Unter der Annahme, dass es keinen Studenten mit leerem
Namen gibt, wird die Bedingung der ersten SELECT Abfrage nie erfüllt. Folglich liefert die erste Abfrage NULL.
Die zweite Abfrage liefert die Spalte accountNumber aus der
Tabelle bankAccounts für den Benutzer mit der ID 42. Die
ID wird zuvor in Erfahrung gebracht oder zufällig gewählt.
Durch UNION wird als Ergebnis nur eine Zeile mit der Spalte accountNumber zurückgegeben. Die Webanwendung wird
dem Benutzer diesen Wert unter der Annahme, es handle
sich um die Spalte semester der Tabelle students, anzeigen.
Auf diese Art und Weise können Daten anderer Tabellen aus
der Datenbank extrahiert werden.
5.2.4
Piggy-Backed Queries
Die Möglichkeit, mehrere Abfragen durch spezielle Delimeter2 zu trennen und somit mehrere Abfragen hintereinander
auszuführen, kann für eine Attacke verwendet werden. Diese Art der Attacke wird Piggy-Backed Query genannt [13].
Bei dieser Attacke wird nicht die eigentliche Abfrage (Listing 9) geändert sondern eine neue Abfrage hinzugefügt [13].
Dadurch kann beliebiger SQL Code auf der Datenbank ausgeführt werden.
Listing 9: SQL Abfrage
s e l e c t ∗ from s t u d e n t s where name = ’ $n ’
Wenn der Platzhalter $n durch die SQL Injection (Listing 10)
ersetzt wird, ist es möglich, die gesamten Benutzertabelle zu
löschen (Listing 11).
Listing 10: SQL Injection
Robert ’ ; drop t a b l e s t u d e n t s −−
Listing 11: Piggy-Backed Query
s e l e c t ∗ from s t u d e n t s where name =
’ Robert ’ ; drop table s t u d e n t s −− ’
2
In vielen SQL Datenbanksystemen wird das Symbol ; standardmäßig als Delimeter verwendet, z.B. in MySQL.
5.2.5
Stored Procedures
Stored Procedures sind Funktionen in Datenbanksystemen.
Viele Datenbanksysteme enthalten fertige Stored Procedures oder bieten die Möglichkeit, diese zu erstellen [8, 14].
Häufig wird fälschlicherweise angenommen, dass Stored Procedures Schutz vor SQL Injections bieten, doch sie sind ebenfalls angreifbar [7]. Wei stellt in [15] Methoden vor, wie Attacken mit Hilfe von Stored Procedures funktionieren und
verhindert werden können.
5.2.6
Inferences
Wenn keine verwertbaren Informationen wie Fehlermeldungen der Datenbank an den Benutzer der Anwendung weitergeleitet werden, muss das Feedback auf eine andere Art und
Weise eingeholt werden.
Blind SQL Injection
Bei dieser Technik wird auf Informationen geschlossen.
Zum Beispiel war eine SQL Injection wie 100 and 1=1
auf einer ID wahrscheinlich erfolgreich, wenn die Webseite genau den selben Inhalt anzeigt wie wenn 100
übergeben wird. Eine detaillierte Beschreibung wie Blind
SQL Injections funktionieren, stellt Spett in [16] vor.
Timing SQL Injection
Wenn absolut keine verwertbaren Informationen erlangt werden können, ist die einzige Möglichkeit eine Timing SQL Injection. Dabei wird die Zeit, die eine SQL Abfrage braucht gemessen und dazu benutzt
Rückschlüsse auf den Erfolg der Injection zu ziehen.
Timing SQL Injections werden in [7, 17] detailliert behandelt.
5.3
Beispiel für einen Angriff
Nachfolgend wird ein Beispiel für eine SQLIA in PHP und
MySQL vorgestellt.
1
2
3
Listing 12: SQLIV in PHP
$username = $ GET [ ”username ” ] ;
$query = ” s e l e c t ∗ from u s e r s where
username = ’ ” . $username . ” ’ ” ;
$ r e s u l t = m y s q l i q u e r y ( $con , $query ) ;
In Listing 12 wird in einem (unvollständig dargestellten)
PHP Skript eine SQL Abfrage an eine MySQL Datenbank
gesendet. Die Abfrage wird dynamisch generiert und hängt
von dem per HTTP GET übergebenen Parameter username ab. Die fehlende Eingabeüberprüfung in diesem Beispiel
ist eine gravierende Schwachstelle, die für eine SQL Injection genutzt werden kann und somit eine SQLIV darstellt.
Durch den Aufruf der URL dieses PHP Skripts kann die SQLIA durchgeführt werden (Listing 13). Dabei muss die SQL
Injection in URL encoding [18] übergeben werden, damit alle
Sonderzeichen korrekt an das Skript übertragen werden.
Listing 13: SQL Injection durch URL
http :// www . example . com / script . php ? username
= Robert %27%3 B %20 drop %20 table %20 users %3
B %20 - -%20
Der Angriff in Listing 13 verwendet die Angriffsart PiggyBacked Query und basiert auf der SQL Injection aus Listing 10. Dem Angreifer ist es möglich, durch den Aufruf der
URL die Tabelle users zu löschen.
6.
GEGENMAßNAHMEN
Im Folgenden werden drei mögliche Gegenmaßnahmen vorgestellt: Defensives Programmieren, Zugriffsbeschränkungen
im DBMS und automatisierte Schwachstellenerkennung.
6.1
Defensives Programmieren
Das Absichern einer Anwendung gegen SQL Injections beginnt idealerweise bereits beim Erstellen der Anwendung.
Durch Defensives Programmieren werden SQLIVs bereits
während der Entwicklung vermieden. Da eine zeit- und kostenaufwändige Nachbesserung der Anwendung vermieden wird,
sollte Defensives Programmieren stets betrieben werden, insbesondere bei Neuentwicklungen. Eine große Hilfe für Programmierer stellt das OWASP SQL Injection Prevention
Cheat Sheet [2] dar. In diesem Dokument werden Methoden
und Programmierpraktiken vorgestellt, die SQL Injections
effektiv verhindern können. Das Grundprinzip des Defensiven Programmierens ist All Input Is Evil!“ [9]. Dement”
sprechend sollten alle Eingaben der Anwendung, insbesondere Benutzereingaben, als potentielle Angriffspunkte gesehen
werden.
6.1.1
Escaping
Escaping ist eine Technik, Eingaben so zu verändern, dass
SQL Steuerzeichen, wie ’ oder ; vom SQL Interpreter ignoriert bzw. als Teil der Zeichenkette betrachtet werden. Escaping ist eine weit verbreitete Methode, um SQL Injections
zu verhindern. Listing 14 zeigt, wie durch das Voranstellen des Escaping Symbols \ das Steuerzeichen ’ als Teil der
Zeichenkette Scarlett O’Hara interpretiert wird und somit
die Struktur der SQL Abfrage durch die Zeichenkette nicht
verändert wird.
Listing 14: Beispiel für Escaping
s e l e c t ∗ from u s e r s
where name = ’ S c a r l e t t O\ ’ Hara ’
Durch Programmiersprachen und Anwendungsframeworks,
die Methoden für automatisches Escaping anbieten, kann
dem Programmierer die Arbeit erleichtert werden. Nachfolgend wird eine Auswahl von Escaping Methoden in PHP
vorgestellt.
magic quotes gpc
Wenn diese PHP Einstellung gesetzt ist, werden Eingaben, die dem Skript als Parameter übergeben werden
(z.B. per GET), automatisch durch Escaping Funktionen behandelt. Diese Einstellung sollte aber nicht
verwendet werden, da sie keinen vollständigen Schutz
vor SQL Injections bietet [19].
addslashes(...)
Diese Funktion wird zwar häufig für Escaping verwendet, bietet aber nicht unbedingt Schutz vor SQL Injections, da sie nicht alle Möglichkeiten von Injections
abdeckt [20]. Eine bessere Alternative sind datenbankspezifische Escaping Funktionen.
mysql real escape string(...)
Diese MySQL spezifische Funktion bietet den besten
Schutz, falls MySQL verwendet wird. Dennoch gibt es
Exploits [21].
Viele Escaping Techniken können durch Alternate Encodings
[7] umgangen werden. Somit bietet Escaping keinen vollständigen Schutz vor SQL Injections. Daher sollten sich Anwendungen nicht nur auf Escaping verlassen, sondern weitere
Schutzmaßnahmen anwenden.
6.1.2
Datentypsicherheit
Durch die Überprüfung des Datentyps werden ebenfalls viele
SQL Injections vermieden, weil Steuerzeichen nicht bis zum
SQL Interpreter gelangen können.
1
2
3
4
Listing 15: Beispiel für Datentypsicherheit
$ i = $ GET [ ” u s e r i d ” ] ;
$ i = intval ( $ i ) ;
$query = ” s e l e c t ∗ from u s e r s where i d
= ”. $i ;
$ r e s u l t = m y s q l i q u e r y ( $con , $query ) ;
In einer SQL Abfrage wie in Listing 15 wird die ID des Benutzers in der Where-Bedingung überprüft. Wenn bekannt
ist, welcher Datentyp das Feld id hat (hier z.B. Integer),
kann die Eingabe für den Platzhalter $i vorher in einen Integer umgewandelt werden (Zeile 2). An dieser Stelle wird nun
eine SQL Injection verhindert. Diese Technik funktioniert
sehr gut bei numerischen Datentypen. Aufwändiger wird es
bei Datums- und Zeittypen und vor allem bei String-Typen,
also Zeichenketten. Bei diesen Datentypen bietet es sich an,
White List Input Validation anzuwenden.
6.1.3
White List Input Validation
Bei White List Input Validation [22] werden nur bestimmte
Zeichen in der Eingabe zugelassen (whitelisting). Eine Realisierung ist z.B. mit Regular Expressions möglich.
Listing 16: Beispiel für White List Input Validation
1 $p = $ GET [ ”phone ” ] ;
2 i f ( ! preg match ( ”/ ˆ ( [ 0 − 9 ] | − ) ∗ $ / i ” , $p ) )
3 {
4
e x i t ( ” I n v a l i d phone number ”) ;
5 }
6 $query = ” s e l e c t name from u s e r s where
phone = ” . $p ;
7 $ r e s u l t = m y s q l i q u e r y ( $con , $query ) ;
Listing 16 zeigt ein Beispiel in PHP. Die White List Input
Validation in Zeile 2 erlaubt nur bestimmte Arten von Zeichenketten, hier Telefonnummern. In Telefonnummern sind
in diesem Beispiel nur Ziffern und das Symbol - erlaubt.
Wenn ein anderes Zeichen in der Zeichenkette vorhanden
ist, wird das Programm abgebrochen.
6.1.4
Eigene Fehlerausgabe
Eine wichtige Gegenmaßnahme ist, Fehlermeldungen sehr
knapp zu halten bzw. nicht direkt an die Benutzer der Anwendung weiterzugeben. Das verringert das Risiko einer SQL
Injection stark, weil dem Angreifer die Angriffsvorbereitung
(Abschnitt 5.1), insbesondere Fingerprinting und das Herausfinden von Datenbankschemata, erschwert wird. Die Angriffsart Ungültige Abfragen (Abschnitt 5.2.2) ist dann nicht
möglich, weil sie auf detaillierten Fehlermeldungen aufbaut.
Deswegen ist es von Vorteil, in eine Anwendung eine Einstellung einzubauen, die definiert ob die Anwendung im Debugbzw. Entwicklungsmodus läuft. Wenn diese Einstellung aktiviert ist, werden detaillierte Fehler ausgegeben, die die Entwickler in ihrer Tätigkeit bestmöglich unterstützen. Wenn
die Anwendung fertig entwickelt ist, wird diese Einstellung
deaktiviert und es werden nur noch allgemeine Fehlermeldungen, wie z.B. Datenbankfehler“, zurückgegeben.
”
6.1.5
Prepared Statements
Prepared Statements, auch Parameterized Queries genannt,
sind die sicherste Maßnahme gegen SQL Injections und sollten von allen Entwicklern verwendet werden [2]. Bei Prepared Statements muss der Entwickler erst die Struktur der
SQL Abfrage definieren und danach die Daten, die in die
Struktur eingesetzt werden. Durch die Trennung von Struktur und Daten ist keine Veränderung der Struktur durch
manipulierte Daten mehr möglich und somit werden SQL
Injections effektiv verhindert.
1
2
3
4
5
6
7
8
9
10
11
12
13
Listing 17: Beispiel für Prepared Statements
/∗ I n i t i a l i z e d a t a b a s e c o n n e c t i o n ∗/
$ m y s q l i = new m y s q l i ( ” l o c a l h o s t ” , ” u s e r
” , ”password ” , ”db ”) ;
/∗ C r e a t e Prepared S t a t e m e n t ∗/
$stmt = $mysqli −>p r e p a r e ( ” s e l e c t ∗ from
u s e r s where name = ? and p i n = ? ”)
/∗ Bind p a r a m e t e r s ∗/
$name = $ GET [ ”name ” ]
$ p i n = $ GET [ ”p i n ” ]
$stmt−>bind param ( ” s i ” , $name , $ p i n ) ;
/∗ E x e c u t e s t a t e m e n t ∗/
$stmt−>e x e c u t e ( ) ;
In Listing 17 wird ein PHP Beispiel für eine SQL Abfrage
unter Verwendung von Prepared Statements gezeigt. Dieses Minimalbeispiel soll nur das Prinzip verdeutlichen und
verzichtet deswegen auf Fehlerbehandlung. In Zeile 5 wird
das Prepared Statement erstellt. Hier ist darauf zu achten,
dass keine Eingaben direkt in den Query-String eingebaut
werden, sondern stattdessen als Platzhalter das Symbol ?
verwendet wird. Die Platzhalter werden in Zeile 10 beim
sogenannten bind -Vorgang durch Werte ersetzt. Dabei werden auch die Datentypen festgelegt: si bedeutet, dass zwei
Platzhalter ersetzt werden, der erste vom Typ String (s) und
der zweite vom Typ Integer (i). Durch den bind -Vorgang ist
also automatisch Datentypsicherheit gegeben. Bei Prepared
Statements muss kein gesondertes Escaping betrieben werden, da im bind -Vorgang die Struktur der SQL Abfrage nicht
mehr verändert werden kann. Nach Zeile 10 kann das Prepared Statement $stmt verwendet werden, um sichere SQL
Abfragen durchzuführen.
6.2
Zugriffsbeschränkungen im DBMS
Das Datenbanksystem (auch DBMS, Datenbankmanagementsystem) muss durch Zugriffskontrollen abgesichert sein. Die
Datenbankverbindung zwischen einer Anwendung und dem
SQL Server kann durch die Verwendung von Benutzername
und Passwort geschützt werden. Zwei verschiedene Datenbanken auf einem Server dürfen sich niemals Benutzername
und Passwort teilen, weil sonst bei einem Bekanntwerden
der Zugangsdaten mehrere Datenbanken auf einmal betroffen sind. Außerdem darf der Benutzer root niemals für Datenbankverbindungen in Anwendungen verwendet werden,
da in der Standardeinstellung zu viele Rechte an diesen Benutzer vergeben sind.
SQL Datenbanken wie MySQL erlauben sehr gezieltes Setzen von Rechten für Datenbankbenutzer [23]. Es gilt der
Grundsatz:
So viele Rechte wie nötig, aber so wenig wie möglich vergeben.
Wird in einer Anwendung beispielsweise niemals ein DROP
ausgeführt, sollten auch keine DROP Rechte an den Datenbankbenutzer, der in der Anwendung verwendet wird, vergeben sein.
Es empfiehlt sich außerdem, vor allem bei großen Anwendungen, in unterschiedlichen Teilen der Anwendung verschiedene Datenbankbenutzer zu verwenden, die jeweils so wenig
Rechte wie möglich haben. Wenn eine Attacke erfolgreich
ist, kann der Angreifer nur in diesem Teil der Anwendung
agieren und hat keinen oder nur eingeschränkten Zugriff auf
andere Teile der Datenbank.
6.3
Automatisierte Schwachstellenerkennung
Es gibt Tools, die automatisiert Schwachstellen in Anwendungen finden und oft auch automatisiert beheben können.
Dieser Abschnitt bietet einen Überblick über dieses Thema
sowie weiterführende Literatur dazu.
6.3.1
Codeanalysetools
Tools in dieser Kategorie analysieren den Code der Anwendung, um Schwachstellen zu finden. Eine Möglichkeit ist beispielsweise der PSR-Generator Algorithmus (Prepared Statement Replacement Generator Algorithmus) [24], der alle dynamischen SQL Abfragen durch Prepared Statements ersetzt. In [25, 26, 24] werden Codeanalysetools näher besprochen.
6.3.2
Laufzeitanalysetools
Tools dieser Art versuchen eine laufende Anwendung automatisiert mit gängigen Attacken anzugreifen. Der Code der
Anwendung muss dem Tool nicht bekannt sein. Anschließend
werden gefundene Sicherheitslücken angezeigt und der Entwickler kann seinen Code verbessern. Diese Tools können
jedoch auch zur Angriffsvorbereitung missbraucht werden.
Halfond, Viegas und Orso behandeln in [26] Laufzeitanalysetools.
Es existiert eine weitere Art von Laufzeitanalysetools, die
ständig zusammen mit der Anwendung auf dem Server laufen. Sie können z.B. durch Bibliotheken oder Middlewares
(zwischen Anwendung und Datenbanksystem) den Verkehr
zwischen Anwendung und SQL Server überwachen und versuchen Attacken zu erkennen und zu verhindern (intrusion
detection) [27, 26]. Diese Systeme führen allerdings einen
Overhead ein, weil sie permanent laufen müssen.
7.
ZUSAMMENFASSUNG
SQL Injections sind nach wie vor eine große Bedrohung für
Anwendungen. Wenn aber die im Paper vorgestellten Prinzipien beachtet werden, können die meisten SQL Injections
verhindert werden.
Die wichtigste Gegenmaßnahme ist die Verwendung von Prepared Statements, weil nur mit dieser Technik Struktur und
Daten einer SQL Abfrage getrennt werden. Dadurch werden SQL Injections nahezu unmöglich gemacht. Zusätzlich
muss immer darauf geachtet werden, dass die Eingaben ausreichend überprüft werden, vor allem durch Datentypüberprüfung und White List Input Validation. Escaping sollte
für alle Benutzereingaben durchgeführt werden, aber nicht
als alleinige Maßnahme eingesetzt werden. Wenn die Datenbankbenutzer nur minimale Rechte haben, wird im Fall eines
erfolgreichen Angriffs der Schaden begrenzt.
Wenn all diese Empfehlungen umgesetzt werden, wird der
Code einer Anwendung sehr viel sicherer und nahezu unverwundbar gegenüber SQL Injections.
8.
LITERATUR
[1] M. Shema: Seven Deadliest Web Application Attacks,
Syngress, 2010
[2] SQL Injection Prevention Cheat Sheet,
https://www.owasp.org/index.php/
SQL_Injection_Prevention_Cheat_Sheet
(Zugriffsdatum: 22.12.2013)
[3] Cenzic Inc.: Application Vulnerability Trends Report
2013, https://info.cenzic.com/2013-ApplicationSecurity-Trends-Report.html
(Zugriffsdatum: 22.12.2013)
[4] Open Web Application Security Project (OWASP),
https://www.owasp.org/ (Zugriffsdatum: 22.12.2013)
[5] OWASP Top 10 2013,
https://www.owasp.org/index.php/Top_10_2013Top_10
(Zugriffsdatum: 22.12.2013)
[6] Eckert: IT-Sicherheit, Kapitel 3.5.3, Oldenbourg
Verlag, 2012
[7] William G.J. Halfond, Jeremy Viegas, Alessandro
Orso: A Classification of SQL Injection Attacks and
Countermeasures, IEEE International Symposium on
Secure Software Engineering (ISSSE), 2006
[8] MySQL create procedure and create function Syntax,
http://dev.mysql.com/doc/refman/5.5/en/createprocedure.html
(Zugriffsdatum: 22.12.2013)
[9] Michael Howard, David LeBlanc: Writing Source
Code, Second Edition, Chapter 10: All Input Is Evil!“,
”
Microsoft Press, 2004
[10] William G.J. Halfond, Jeremy Viegas, Alessandro
Orso: A Classification of SQL Injection Attacks and
Countermeasures, Proceedings of the IEEE
International Symposium on Secure Software
[11]
[12]
[13]
[14]
[15]
[16]
[17]
[18]
[19]
[20]
[21]
[22]
[23]
[24]
[25]
[26]
[27]
Engineering, Kapitel 2.2, Performing database
”
finger-printing“, 2006
William G.J. Halfond, Jeremy Viegas, Alessandro
Orso: A Classification of SQL Injection Attacks and
Countermeasures, Proceedings of the IEEE
International Symposium on Secure Software
Engineering, Kapitel 2.2, Determining database
”
schema“, 2006
MySQL Kommentare,
http://dev.mysql.com/doc/refman/5.1/de/
comments.html (Zugriffsdatum: 22.12.2013)
Neha Mishra, Sunita Gond: Defenses To Protect
Against SQL Injection Attacks, IJARCCE, 2013
Michael Howard, David LeBlanc: Writing Source
Code, Second Edition, Microsoft Press, 2004
Ke Wei, Muthusrinivasan Muthuprasanna, Suraj
Kothari: Preventing SQL injection attacks in stored
procedures., Software Engineering Conference 2006,
IEEE, 2006
Kevin Spett: Blind sql injection., SPI Dynamics Inc,
Firmeninternes Paper, 2003
Ferruh Mavituna: Deep Blind SQL Injection., White
Paper, 2008
Uniform Resource Identifier (URI): Generic Syntax,
http://tools.ietf.org/html/rfc3986
(Zugriffsdatum: 22.12.2013)
PHP: Why not to use Magic Quotes,
http://www.php.net/manual/en/
security.magicquotes.whynot.php
(Zugriffsdatum: 22.12.2013)
PHP: addslashes, http://de3.php.net/addslashes
(Zugriffsdatum: 22.12.2013)
Get around mysql real escape string(),
http://stackoverflow.com/a/12118602/2013757
(Zugriffsdatum: 22.12.2013)
Input Validation Cheat Sheet,
https://www.owasp.org/index.php/
Input_Validation_Cheat_Sheet
(Zugriffsdatum: 22.12.2013)
Kemper, Eickler: Datenbanksysteme, Kapitel 12.2,
Oldenbourg Verlag, 2009
Sayyed Mohammad Sadegh Sajjadi, Bahare Tajalli
Pour: Defenses To Protect Against SQL Injection
Attacks, IJCCE, Vol. 2 No. 5, 2013
Lwin Khin Shar and Hee Beng Kuan Tan: Defeating
SQL Injection, Nanyang Technological University,
IEEE, 2013
William G.J. Halfond, Jeremy Viegas, Alessandro
Orso: A Classification of SQL Injection Attacks and
Countermeasures, IEEE International Symposium on
Secure Software Engineering (ISSSE), Kapitel 5.2,
Detection and Prevention Techniques“, 2006
”
Frank S. Rietta: Application layer intrusion detection
for SQL injection., Proceedings of the 44th annual
Southeast regional conference, ACM, 2006
Herunterladen