SQLite - 注入



如果您透過網頁獲取使用者輸入並將其插入 SQLite 資料庫,則您可能面臨一個稱為 SQL 注入的安全問題。在本節中,您將學習如何幫助防止這種情況發生,並幫助您保護您的指令碼和 SQLite 語句。

注入通常發生在您向用戶索取輸入(例如他們的姓名)時,他們提供的不是姓名,而是一個您會在不知情的情況下在資料庫上執行的 SQLite 語句。

永遠不要相信使用者提供的資料,只有在驗證之後才能處理這些資料;通常,這是透過模式匹配來完成的。在下面的示例中,使用者名稱被限制為字母數字字元加下劃線,長度在 8 到 20 個字元之間 - 根據需要修改這些規則。

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";
}

為了演示這個問題,請考慮以下摘錄:

$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username = '{$name}'");

該函式呼叫應該從 users 表中檢索一條記錄,其中 name 列與使用者指定的 name 匹配。在正常情況下,$name 只包含字母數字字元和空格,例如字串 ilia。但是,在這種情況下,透過將一個全新的查詢附加到 $name,對資料庫的呼叫變成了災難:注入的 DELETE 查詢刪除了 users 中的所有記錄。

有些資料庫介面不允許查詢堆疊或在單個函式呼叫中執行多個查詢。如果您嘗試堆疊查詢,則呼叫會失敗,但 SQLite 和 PostgreSQL 會愉快地執行堆疊查詢,執行在一個字串中提供的所有查詢,並造成嚴重的安全問題。

防止 SQL 注入

您可以在 PERL 和 PHP 等指令碼語言中巧妙地處理所有跳脫字元。程式語言 PHP 提供函式 sqlite_escape_string() 來轉義對 SQLite 特殊的輸入字元。

if (get_magic_quotes_gpc()) {
   $name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username = '{$name}'");

儘管編碼使插入資料安全,但對於包含二進位制資料的列,它將使簡單的文字比較和查詢中的 LIKE 子句無法使用。

注意 - addslashes() 不應用於為 SQLite 查詢引用字串;這會在檢索資料時導致奇怪的結果。

廣告