SQL-Injections sind eine weit verbreitete Art von Schwachstellen in Webseiten, welche hohes Schadenspotenzial aufweisen können. Dieser Artikel dreht sich genau um diese Art von Injections und zeigt auf, was sie sind, weshalb sie auftreten können und wie sie behoben werden können.
Inhaltsverzeichnis
Was sind SQL-Injections?
Sobald eine Applikation auf eine Datenbank zugreifen muss und dabei Benutzereingaben verwendet werden, zum Beispiel um eine Suchanfrage zu tätigen, ist potenziell eine SQL-Injection möglich, wenn die Abfrage nicht sicher gemacht wird. Mit einer solchen Injection kann es einem Angreifer möglich sein, Zugriff auf die Datenbank zu erhalten, Daten auszulesen, sie zu manipulieren oder im schlimmsten Fall sogar eine interaktive Kommandozeile auf dem Datenbankserver zu erhalten. Trotz des grossen Schadenspotenzials sind diese Sicherheitslücken immer noch häufig zu finden. OWASP Top 10 (siehe Artikel OWASP Top 10:2021 – Kalter Kaffee neu aufgekocht?) stuft SQL-Injection als Platz 3 der häufigsten Sicherheitsrisiken ein (Zusammen mit anderen Injections): https://owasp.org/www-project-top-ten/
SQL-Injections können manuell oder mit Tools ausgenutzt werden. Das wohl bekannteste Tool ist SQLmap – ein automatisches Werkzeug zum Ausnutzen von SQL-Injections und Datenbankübernahmen. Mit einem solchen Programm können die meisten Schwachstellen einfach und schnell ausgenutzt werden. Falls Filter im Einsatz sind, welche Benutzereingaben einschränken, um SQL-Injections zu verhindern, müssen diese oft manuell umgangen werden.
Hier ist ein Beispiel, in dem ein Login umgangen wird, um mit einer SQL-Injection Zugriff auf den Administrator Benutzer zu erhalten. Als Benutzername wird Administrator angegeben (ohne ein Passwort anzugeben). Das Login schickt folgende Informationen an den Server:
administrator
Im Hintergrund wird folgender SQL-Befehl in der Datenbank ausgeführt:
SELECT * FROM users WHERE username = 'administrator' AND password = ''
Das Login wird nicht erfolgreich sein, denn es wurde kein Passwort angegeben. Nun wird versucht, mittels einer SQL-Injection, das Login zu umgehen. Eine Möglichkeit ist, den Rest der SQL-Abfrage auszukommentieren. Ein Kommentar in SQL wird mit --
initiiert. Der Benutzername in der Anfrage muss noch mit einem '
beendet werden, damit der Kommentar auch ausgeführt wird. Zusammen ergibt das die folgende Eingabe im Feld für den Benutzernamen:
administrator'--
Auf dem Server wird die Abfrage so auskommentiert, dass das Password gar keine Rolle mehr spielt. Das ist ein sehr einfacher Bypass für eine Login Funktion, sofern keine Sicherheitsmassnahmen eingebaut wurden. Im Hintergrund wird folgender SQL-Befehl ausgeführt:
SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
Der Server interpretiert die Anfrage nun wie folgt (da der Rest auskommentiert ist):
SELECT * FROM users WHERE username = 'administrator'
Ein Angreifer wird so eingeloggt, obwohl das Passwort gar nicht bekannt ist oder eingegeben wurde. Bei der Oneconsult testen wir Webapplikationen auf SQL-Injections wie diese und noch weit kompliziertere, bei welchen auch Schutzmechanismen im Spiel sind.
Weshalb treten SQL-Injections auf?
SQL-Injections treten auf, wenn Benutzereingaben nicht bereinigt werden. Ein Beispiel ist das Zeichen ‘, das viele SQL-Injections auslösen kann. Es wird mithilfe eines solchen Sonderzeichens ein SQL-Befehl eingeschleust, welcher vom SQL-Interpreter ausgeführt wird. Andere Zeichen, welche eine SQL-Injection auslösen können, sind \, « oder auch ;. Manchmal wird auch gar kein Sonderzeichen benötigt (falls es sich nicht um Strings, sondern Zahlenwerte handelt). Ein Beispiel dafür wäre folgende Abfrage:
SELECT * FROM users WHERE user_id = [ID]
Sie treten auch auf, wenn der SQL-Befehl einfach aus Strings zusammengesetzt wird, welche aus Benutzereingaben bestehen.
Manuell kann man diese sowohl im Code als auch bei einem Penetration Test finden. Kompliziertere SQL-Injections findet man eher bei einem Code Review. Bei einem Code Review kann man genau schauen, wie Benutzereingaben weiterverarbeitet werden.
Wie können SQL-Injections verhindert werden?
Es gibt mehrere Möglichkeiten SQL-Injections zu verhindern. Eine Möglichkeit sind die sogenannten SQL Prepared Statements, auch parametrisierte Abfragen genannt. Anstatt verkettete Strings zu verwenden, wird die SQL-Abfrage schon vorbereitet und im Nachhinein werden die Benutzereingaben hinzugefügt. Hier ist ein möglicher Code, der anfällig für eine SQL Injection ist:
String query = "SELECT * FROM users WHERE username = '"+ username + "'"; Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query);
Dieser Java Code kann nun wie folgt umgeschrieben werden, um die Injection zu verhindern:
PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE username = ?"); statement.setString(1, username); ResultSet resultSet = statement.executeQuery();
Diese Methode funktioniert nur in gewissen Teilen der Abfrage (zum Beispiel in WHERE, INSERT und UPDATE). Um andere Teile zu schützen, zum Beispiel ORDER BY oder Tabellennamen, sollte eine Whitelist verwendet werden, die die erlaubten Inputs einschränkt. Von einem Blacklist-Ansatz ist abzuraten, denn so können Sonderzeichen, die zu SQL-Injections führen, übersehen werden.
Das OWASP Cheat Sheet kann beim Verhindern von SQL-Injections eine enorme Hilfe sein: SQL Injection Prevention Cheat Sheet
Fazit
Alle Applikationen sollten auf SQL-Injection überprüft werden. Sie verursachen nicht nur Schaden an Kunden oder Benutzern, sondern sie können auch einer Firma schaden. Angenommen, ein Spital wird durch eine SQL-Injection angegriffen und alle Patientendaten werden aus der Datenbank extrahiert und veröffentlicht, so schadet dies allen Patienten, aber auch dem Spital, da dieses nun einen hohen Reputationsschaden erwarten kann.
Im Idealfall sollten alle Applikationen einem Penetration Test unterzogen werden. Ist dies nicht möglich, sollten zumindest unternehmenskritische Applikationen getestet werden. Dabei wird nicht nur nach SQL-Injections gesucht, sondern auch nach diversen andere Schwachstellen.