Samstag, 4. Februar 2012 |
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.
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();
Um SQL Injection zu verhindern oder zumindest ihre Auswirkungen zu mindern, sind eine Reihe weiterer Maßnahmen hilfreich:
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"