Um zu verhindern, dass Benutzer ungültige Werte in SQL-Anweisungen eingeben und dadurch den Datenbestand unkontrolliert verändern oder das Verhalten der Datenbankanwendung ändern (SQL Injection), empfehlen wir die Verwendung von Prepared Statements.
Die folgende Tabelle zeigt, für welche MaxDB-Schnittstellen Sie welche Prepared Statements verwenden können.
MaxDB-Schnittstellen: PreparedStatements
Schnittstelle |
Prepared Statements |
JDBC |
Klasse PreparedStatement |
ODBC |
Methode SQLPrepare |
SQLDBC |
Klasse SQLDBC_PrepareStatement |
PHP |
maxdb_prepare |
Perl |
prepare |
Python |
Methode prepare, Klasse SAPDB_Prepared |
Weitere Informationen zu den MaxDB-Schnittstellen finden Sie in Konzepte des Datenbanksystems, Schnittstellen.
Die Tabelle APPLICATION_USER enthält die Benutzer und Kennwörter einer Datenbankanwendung, die über die MaxDB-JDBC-Schnittstelle auf die Datenbankinstanz DEMODB zugreift.
Unsichere Anweisung
Die folgende Implementierung der Benutzeranmeldung ist unsicher, weil sie von einer Person dazu missbraucht werden kann, durch die Eingabe eines ungültigen Werts Zugriff auf die Datenbankinstanz zu erhalten, ohne ein gültiges Kennwort anzugeben.
Statement s = connection.createStatement();
ResultSet rs = s.executeQuery("SELECT * FROM APPLICATION_USERS WHERE username = '" + username + "' and password = '" + password + "'");
if(rs.next()) {
// ... continue with successful logon
} else {
// ... unsuccessful logon
}
Wenn eine Person einen gültigen Benutzernamen für die Datenbankanwendung kennt, dann kann sie sich anmelden, ohne ein gültiges Kennwort anzugegeben. Es genügt, für password beispielsweise den Wert abcdefg′ or 1=1 anzugeben.
Das Kennwort wird dann folgendermaßen zusammengesetzt:
password='abcdefg' or 1=1'
Weil 1=1 immer wahr ist, wird auch der gesamte Ausdruck für das Kennwort vom Datenbanksystem immer als wahr ausgewertet, unabhängig davon, ob abcdefg ein gültiges Kennwort ist oder nicht.
Verbesserte Anweisung
Die folgende Implementierung der Benutzeranmeldung verwendet Prepared Statements und schützt vor der oben beschriebenen SQL-Injection, weil als Kennwort keine Sonderzeichen wie beispielsweise ' mehr eingegeben werden können.
PreparedStatement ps = connection.prepare("SELECT * FROM APPLICATION_USERS WHERE username=? and password=?");
ps.setString(1, username);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
if(rs.next()) {
// ... continue with successful logon
} else {
// ... unsuccessful logon
}