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он содержал бы только буквенно-цифровые символы или пробелы, например строку ilia. Но здесь к $name добавляется совершенно новый запрос. Этот вызов базы данных вызовет катастрофическую проблему: внедрённый запрос DELETE удалит все записи из users.
Хотя уже существуют интерфейсы баз данных, которые не допускают объединения запросов или выполнения нескольких запросов в одном вызове функции, и вызов завершится ошибкой, если попытаться объединить запросы, SQLite и PostgreSQL по-прежнему допускают составные запросы, то есть все запросы, переданные одной строкой, выполняются, что может привести к серьёзным проблемам безопасности.
Предотвращение SQL-инъекций
В таких скриптовых языках, как PERL и PHP, можно умело обрабатывать все escape-символы. Язык программирования PHP предоставляет строковую функциюSQLite3::escapeString($string)иsqlite_escape_string()для экранирования входных символов, специальных для SQLite.
Примечание: версия PHP, необходимая для использования функцииsqlite_escape_string(), — этоPHP 5 < 5.4.0。
PHP 5 >= 5.3.0, PHP 7 используют следующую функцию:
SQLite3::escapeString($string);//$string为要转义的字符串
Следующий метод не поддерживается в последних версиях PHP:
if (get_magic_quotes_gpc())
{
$name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username='{$name}'");
Хотя кодирование делает вставляемые данные безопасными, оно делает простое текстовое сравнение невозможным. В запросах для столбцов, содержащих двоичные данные,LIKEусловие использовать нельзя.
Обратите внимание, что addslashes() не следует использовать для заключения строк в кавычки в запросах SQLite, так как это может привести к странным результатам при извлечении данных.
Другие расширения