开发学院

您的位置:首页>教程>正文

教程正文

SQLite 注入

SQLite 注入

  如果通过网页获取用户输入并将其插入到SQLite数据库中,就有可能会引发被称为SQL注入的安全问题。在本小节中,您将了解如何防止这种情况发生,并帮助您保护脚本和SQLite语句的安全。

  注入通常发生在你要求用户输入信息的时候,比如您希望用户输入真实的名字,但是对方备有用心的输入了一条sql语句,如果不做处理该条语句就会被执行导致数据泄露或者其他安全问题。

  永远不要相信用户提供的数据,只有在验证后才处理这些数据;通常,这是通过模式匹配来完成的。在下面的例子中,用户名被限制为字母数字字符加下划线,长度在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追加一个新的sql语句,那么执行这个语句就会变成一场灾难:注入的删除查询会删除用户的所有记录。

  有些数据库不允许在单个函数调用中堆叠查询或执行多个查询。如果尝试堆叠查询,调用会失败,但是SQLite和PostgreSQL会愉快地执行堆叠查询,执行一个字符串中提供的所有查询,引发严重的安全问题。

防止注入

  在PERL和PHP这样的脚本语言中,你可以巧妙地处理所有转义字符。编程语言PHP提供函数字符串sqlite_escape_string()来转义SQL特有的输入字符。

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

  虽然编码使插入数据变得安全,但是它会使查询中的文本比较和类似子句对于包含二进制数据的列不可用。

  注意:addslashes()不应用于为SQLite查询引用字符串;检索数据时会导致奇怪的结果。