SQLite Injection
Wenn Ihre Website es Benutzern ermöglicht, Daten über Webseiten einzugeben, und diese Eingabe in eine SQLite-Datenbank einfügt, dann stehen Sie vor einem Sicherheitsproblem, das als SQL-Injection bekannt ist. In diesem Kapitel wird erklärt, wie Sie dies verhindern und Ihre Skripte und SQLite-Anweisungen sicher halten können.
Injection tritt typischerweise auf, wenn Benutzereingaben angefordert werden, beispielsweise wenn ein Benutzer aufgefordert wird, seinen Namen einzugeben, stattdessen aber eine SQLite-Anweisung eingibt, die unwissentlich auf der Datenbank ausgeführt wird.
Vertrauen Sie niemals Daten, die von Benutzern bereitgestellt werden, verarbeiten Sie also nur Daten, die validiert wurden. Diese Regel wird durch Musterabgleich umgesetzt. Im folgenden Beispiel ist der Benutzername auf alphanumerische Zeichen oder Unterstriche beschränkt, und seine Länge muss zwischen 8 und 20 Zeichen liegen - ändern Sie diese Regeln nach Bedarf.
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){
$db = new SQLiteDatabase('filename');
$result = @$db->query("SELECT * FROM users WHERE username=$matches[0]");
}else{
echo "username not accepted";
}
Um dieses Problem zu veranschaulichen, betrachten Sie diesen Auszug:
$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username='{$name}'");
Der Funktionsaufruf soll Datensätze aus der Tabelle users abrufen, bei denen die Spalte name dem vom Benutzer angegebenen Namen entspricht. Unter normalen Umständen würde$namenur alphanumerische Zeichen oder Leerzeichen enthalten, wie die Zeichenfolge ilia. Hier wird jedoch eine völlig neue Abfrage an $name angehängt. Dieser Datenbankaufruf verursacht ein verheerendes Problem: Die injizierte DELETE-Abfrage löscht alle Datensätze aus users.
Obwohl es bereits Datenbankschnittstellen gibt, die kein Query-Stacking oder die Ausführung mehrerer Abfragen in einem einzigen Funktionsaufruf erlauben und der Aufruf fehlschlägt, wenn Sie versuchen, Abfragen zu stapeln, erlauben SQLite und PostgreSQL weiterhin gestapelte Abfragen, was bedeutet, dass alle in einer einzigen Zeichenfolge bereitgestellten Abfragen ausgeführt werden, was zu ernsthaften Sicherheitsproblemen führen kann.
SQL-Injection verhindern
In Skriptsprachen wie PERL und PHP können Sie alle Escape-Zeichen geschickt behandeln. Die Programmiersprache PHP bietet die String-FunktionSQLite3::escapeString($string)undsqlite_escape_string(), um Eingabezeichen zu maskieren, die für SQLite speziell sind.
Hinweis: Die zum Verwenden der Funktionsqlite_escape_string()erforderliche PHP-Version istPHP 5 < 5.4.0。
Für PHP 5 >= 5.3.0, PHP 7 verwenden Sie die folgende Funktion:
SQLite3::escapeString($string);//$string为要转义的字符串
Die folgende Methode wird in den neuesten Versionen von PHP nicht unterstützt:
if (get_magic_quotes_gpc())
{
$name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username='{$name}'");
Obwohl die Kodierung eingefügte Daten sicher macht, steht sie einem einfachen Textvergleich entgegen. In Abfragen ist für Spalten, die Binärdaten enthalten, dieLIKE-Klausel nicht verwendbar.
Bitte beachten Sie, dass addslashes() nicht verwendet werden sollte, um Zeichenfolgen in SQLite-Abfragen zu quoten, da dies beim Abrufen von Daten zu seltsamen Ergebnissen führen kann.
Andere Erweiterungen