Die Verwendung von Prepared SQL Statements bzw. Stored Procedures ist neben der in About Security #12 beschriebenen Prüfung der Benutzereingaben eine weitere Möglichkeit, um SQL-Injection-Angriffe zu verhindern.
N E U ! Security
aktuell
Täglich aktuelle Security-Infos!
Bei der Verwendung von Stored Procedures werden Templates der verwendeten SQL-Abfragen definiert und in der Datenbank gespeichert. Während der Programmausführung werden diese Templates um die übergebenen Parameter erweitert und ausgeführt. Prepared SQL Statements funktionieren ähnlich, die Templates werden jedoch während der Programmausführung an die Datenbank gesendet und von dieser dann gespeichert, ebenfalls um die Parameter erweitert und ausgeführt. Das Hinzufügen weiterer SQL-Befehle über die Parameter ist bei parametrisierten Abfragen nicht möglich.
Ein wichtiger Hinweis: Stored Procedures sind nicht von sich aus vor SQL Injection sicher. Werden sie auf herkömmliche Weise mit den Benutzereingaben aufgerufen, kann SQL-Code eingeschleust werden. Erst durch den parametrisierten Aufruf sind sie nach aktuellem Wissenstand vor SQL-Injection sicher.
Während Stored Procedures von der verwendeten Datenbank unterstützt werden müssen, können Prepared Statements auch vom Datenbank-Interface implementiert werden. Diese Prepared Statements auf der Clientseite bieten die gleiche Sicherheit wie ihre serverseitige Variante, profitieren aber nicht wie diese von etwaigen Optimierungen durch das Datenbanksystem.
Im Folgenden wird der Einsatz von Prepared Statements beschrieben. Ähnlich funktioniert die Verwendung von Stored Procedures.
Prepared Statements
Als Beispiel soll die Abfrage
SELECT * FROM Benutzer WHERE Ort =
aus About Security #11 dienen. Wie dort gezeigt wurde, kann ein Angreifer diese Abfrage für einige Angriffe ausnutzen. Dies ist bei parametrisierten Aufrufen nicht möglich. Dabei werden die Eingaben gefiltert und der Typ entsprechend der gespeicherten Abfrage angepasst.
Allgemein lautet die obige Abfrage als Prepared Statement
SELECT * FROM Benutzer WHERE Ort = ?
Für PHP gibt es je nach verwendeter Datenbank verschiedene Funktionen zum Erstellen vom Prepared Statements. Für PostgreSQL kann man die Abfrage als Prepared Statement als
= pg_prepare("ort_abfrage", 'SELECT * FROM Benutzer WHERE Ort = ');
formulieren. Der Aufruf erfolgt dann über folgenden Funktionsaufruf:
= pg_execute("ort_abfrage", );
Für MySQL sind entsprechende Funktionen in der experimentellen MySQL-Erweiterung MySQLi vorhanden.
Perls datenbankunabhängiges Datenbankmodul DBI stellt folgende Funktionen zur Verfügung:
= ->prepare("SELECT * FROM Benutzer WHERE Ort = ?");
= ->execute( );
In Microsofts .NET-Framework könnte die parametrisierte Abfrage folgendermaßen formuliert werden:
SqlCommad cmd = new SqlCommand("SELECT * FROM Benutzer WHERE Ort = @ort;")
cmd.Parameters.Add("@ort", ort)
Für Java gibt es die Klasse PreparedStatement,
mit der
sich folgende Aufrufe ergeben:
reparedStatement ortabfrage = con.prepareStatement("SELECT * FROM Benutzer WHERE Ort = ?");
ortabfrage.setString(1, ort);
ResultSet rset = ortabfrage.executeQuery();
Weitere Maßnahmen
Um SQL Injection zu verhindern oder zumindest ihre Auswirkungen zu mindern, sind eine Reihe weiterer Maßnahmen hilfreich:
- Der Benutzer, über den die Webanwendung auf die Datenbank zugreift, darf nur die absolut notwendigen Rechte besitzen. Sollen nur Daten abgefragt werden, reichen das Recht für den SELECT-Befehl und die Zugriffsrechte für die Tabellen mit den relevanten Daten aus. Damit kann ein erfolgreicher Angreifer zwar immer noch alle Daten aus diesen Tabellen lesen, aber wenigstens ist ihm keine Manipulation möglich. Niemals darf von einer Webanwendung aus mit Administratorrechten auf die Datenbank zugegriffen werden.
- Sofern möglich, sollte der gesamte Zugriff auf die Datenbank über Stored Procedures ausgeführt werden. Dann benötigt der von der Webanwendung verwendete Datenbankbenutzer nur die Berechtigung zur Ausführung dieser Stored Procedures.
- Nicht benötigte Extended Stored Procedures (z.B. xp_cmdshell für MS SQL), Stored Procedures etc. müssen entfernt oder dem für die Webanwendung verwendeten Datenbankbenutzer der Zugriff darauf verboten werden.
- Um einem Angreifer keine Anhaltspunkte für seinen Angriff zu liefern, dürfen keine ausführlichen Fehlermeldungen ausgegeben werden. Diese sind in einem Logfile besser aufgehoben. Die Logfiles müssen regelmäßig auf verdächtige Einträge überprüft werden.
- Sensitive Daten wie z.B. Passwörter dürfen nur verschlüsselt gespeichert werden.
Database-Intrusion-Protection-Systeme können Angriffe feststellen und abwehren. Sie werden in einer späteren Folge behandelt. In der nächsten Folge geht es um einen weiteren Angriff auf Webanwendungen: Cross-Site Scripting.
Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!
About Security – Übersicht zum aktuellen Thema "Sichere Webanwendungen"
- About Security #11: SQL Injection
- About Security #12: SQL Injection verhindern
- About Security #13: Mit Stored Procedures gegen SQL Injection
- About Security #14: Cross-Site Scripting
- About Security #15: Cross-Site Scripting verhindern
- About Security #16: Skriptcode einschleusen
- About Security #17: HTTP Request Smuggling
- About Security #18: Spielarten des HTTP Request Smuggling, 1
- About Security #19: Spielarten des HTTP Request Smuggling, 2
- About Security #20: HTTP Request Smuggling erkennen und verhindern
- About Security #21: HTTP Response Splitting, 1
- About Security #22: HTTP Response Splitting, 2
- About Security #23: Caches vergiften
- About Security #24: Caches indirekt vergiften
- About Security #25: Entführen von Webseiten
- About Security #26: Gefahren für Webanwendungen
- About Security #27: Gefahren für Webserver
- About Security #28: Standorte für Webserver



















Kommentare