Bundesamt für Sicherheit in der Informationstechnik

M 2.363 Schutz gegen SQL-Injection

Verantwortlich für Initiierung: IT-Sicherheitsbeauftragter, Leiter IT

Verantwortlich für Umsetzung: Administrator, Anwendungsentwickler

Um die Ausnutzung von SQL-Injections (siehe G 5.131 SQL-Injection ) zu verhindern oder zumindest zu erschweren, sind eine Reihe von Maßnahmen zu ergreifen. Diese erstrecken sich über alle Komponenten einer Anwendung, von der Applikation selbst über den Server bis hin zum Datenbank-Managementsystem ( DBMS ).

Maßnahmen bei der Programmierung von Applikationen

Eine der wichtigsten Maßnahmen zur Vermeidung von SQL-Injection ist die sorgfältige Überprüfung und Filterung von Eingaben und Parametern durch die Applikation. Überprüft werden sollte, ob die übergebenen Daten dem erwarteten Datentyp entsprechen. Wird z. B. ein numerischer Parameter erwartet, kann man diesen in PHP ("PHP: Hypertext Preprocessor") mit der Funktion is_numeric() prüfen. Die Filterung hingegen muss dafür sorgen, dass Sonderzeichen wie das Quote-Zeichen ('), das Semikolon (;) und doppelte Bindestriche (--) ignoriert werden.

Sicherer ist der Einsatz von Stored Procedures beziehungsweise Prepared SQL-Statements. Diese werden von vielen Datenbank-Managementsystemen (DBMS) angeboten und sind ursprünglich dazu gedacht, häufiger auftretende Abfragen zu optimieren. Der Vorteil dieser parametrisierten Statements ist, dass Parameter nicht mehr direkt in ein SQL-Statement eingebunden werden. Vielmehr werden diese getrennt vom SQL-Statement separat an die Datenbank übergeben. Das Zusammenführen von Statement und Parametern erfolgt durch das DBMS selbst, wobei die oben genannten Sonderzeichen automatisch maskiert werden.

Um potentiellen Angreifern keine Anhaltspunkte für Angriffe zu liefern, sollte besonderes Augenmerk darauf gelegt werden, dass Applikationen möglichst keine Fehlermeldungen nach außen ausgeben, die Rückschlüsse auf das verwendete System oder auf die Struktur der dahinterliegenden Datenbank zulassen.

Serverseitige Maßnahmen

Die wichtigste Sicherheitsmaßname auf dem Server ist das Härten des Betriebssystems. Um so wenig Angriffspunkte wie möglich zu bieten, werden dabei Maßnahmen ergriffen wie:

  • das Deaktivieren nicht benötigter Dienste,
  • das Löschen nicht benötigter Benutzerkonten,
  • das Einspielen relevanter Patches und
  • das Löschen aller für die Funktion des Servers unnötigen Bestandteile.

Darüber hinaus sollte der Einsatz eines Application-Level-Gateways ( ALG ) (siehe M 5.117 Integration eines Datenbank-Servers in ein Sicherheitsgateway ) erwogen werden. ALGs können auf Applikationsebene die Daten überwachen, die zwischen Webbrowser und Anwendung ausgetauscht werden, und verhindern, dass schädliche Daten den Server erreichen.

Eine weitere zusätzliche Sicherheitsmaßnahme stellt der Einsatz von Intrusion-Detection-Systemen (IDS) und Intrusion-Prevention-Systemen (IPS) dar. IDS analysieren den über ein Netz übertragenen Datenverkehr und erkennen potentiell gefährliche Daten. Die dazu eingesetzten Analysetechniken unterteilen sich in Misuse und Anomaly Detection. Die Misuse Detection versucht, bereits bekannte Angriffsmuster zu erkennen. Die Anomaly Detection verfolgt den Ansatz, die zulässigen Verhaltensmuster zu lernen und Abweichungen davon als Angriff zu identifizieren. Während ein IDS in der Lage ist, Angriffe zu erkennen und Warnungen auszugeben, ist ein IPS in der Lage, entsprechende Reaktionen auszuführen. Die Reaktion kann beispielsweise darin bestehen, die Verbindung zu blockieren, Daten zu verwerfen oder zu ändern.

Bei erhöhten Sicherheitsanforderungen sollte geprüft werden, ob der Einsatz von IDS beziehungsweise IPS zweckmäßig ist.

Datenbankseitige Maßnahmen

Ebenso wie beim Betriebssystem sollte auch eine Härtung der Datenbank erfolgen. Im Falle der Datenbank bedeutet dies z. B.:

  • das Entfernen nicht benötigter Stored Procedures,
  • das Deaktivieren nicht benötigter Dienste,
  • das Löschen nicht benötigter Benutzerkonten und Default Accounts und
  • das Einspielen relevanter Patches.

In diesem Zusammenhang sollte auch ein speziell für den Datenbankzugriff vorgesehener Account angelegt werden, der mit möglichst eingeschränkten Zugriffsrechten auskommen sollte.

Darüber hinaus sollten sensitive Daten, wie z. B. Passwörter, in der Datenbank soweit möglich nur verschlüsselt gespeichert werden.

Von vielen Herstellern werden mittlerweile sogenannte Schwachstellen-Scanner angeboten, die sowohl Applikationen als auch Datenbanken auf Sicherheitslücken, wie beispielsweise mögliche SQL-Injections, überprüfen können.

Beispiel für prinzipielles Vorgehen zur Erstellung von sicherem Code bei Verwendung von PHP und MySQL:

In PHP verhindert die Funktion mysql_real_escape_sting() die Übergabe von Sonderzeichen an eine MySQL-Datenbank. Die Funktion maskiert die in dem übergebenen String enthaltenen Sonderzeichen wie z. B. Quotes und verhindert so SQL-Injections.

Anstatt der folgenden Syntax:

  • $query = "SELECT * FROM users
    WHERE username=
    '" . $_POST['username'] . "'
    AND password=
    '" . $_POST['password'] . "'";
sollte also diese Syntax verwendet werden:
  • $query = "SELECT * FROM users
    WHERE username=
    '" . mysql_real_escape_string($_POST['username']) . "'
    AND password=
    '" . mysql_real_escape_string($_POST['password']) . "'";

Beispiel für sicheren Code bei Verwendung von ASP mit ADO und SQL-Server:

Die Verwendung eines prepared Statements für das obige Beispiel sieht in diesem Fall folgendermaßen aus:

  • $query = "SELECT * FROM users WHERE username=?
    AND password=?"
    Set cmd = Server.CreateObject("ADODB.Command")
    cmd.CommandText = query
    cmd.CommandType = adCmdText
    Set param = cmd.CreateParameter("",adVarChar, adParamInput,
    nMaxUsernameLength, strUsername)
    cmd.Parameters.Append
    Set param = cmd.CreateParameter("",adVarChar, adParamInput,
    nMaxUsernameLength, strPassword)
    cmd.Parameters.Append
    Set rs = cmd.Execute()

Hierbei ist zu beachten, dass die oben aufgeführten Code-Beispiele nur den grundsätzlichen Ansatz zur Vermeidung von SQL-Injection veranschaulichen sollen.

Prüffragen:

  • Werden Eingaben und Parameter durch die Applikation vor Weiterleitung an das Datenbanksystem sorgfältig überprüft und gefiltert?

  • Werden Stored Procedures beziehungsweise Prepared SQL Statements eingesetzt?

  • Ist gewährleistet, dass keine Fehlermeldungen nach außen ausgeben werden, welche Rückschlüsse auf das verwendete System oder auf die Struktur der dahinterliegenden Datenbank zulassen?

Stand: 13. EL Stand 2013