📜  SQLite-注入

📅  最后修改于: 2021-01-04 05:08:58             🧑  作者: Mango


如果您通过网页获取用户输入并将其插入到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}'");

该函数调用应该从用户表中检索一条记录,其中名称列与用户指定的名称匹配。在正常情况下, $ name仅包含字母数字字符,可能还包含空格,例如字符串ilia。但是,在这种情况下,通过在$ name后面附加一个全新的查询,对数据库的调用将变成灾难:注入的DELETE查询将删除用户中的所有记录。

有些数据库接口不允许查询堆栈或在单个函数调用中执行多个查询。如果尝试堆栈查询,则调用将失败,但是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查询引用字符串;检索数据时会导致奇怪的结果。