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}'");
    
    函数调用应该从用户表中检索一条记录,其中名称列与用户指定的名称相匹配。在正常情况下,$name将只包含字母数字字符和空格,例如字符串 ilia。然而,在这种情况下,通过向 $name 附加一个全新的查询,对数据库的调用变成了一场灾难:注入的 DELETE 查询会删除用户的所有记录。
    有些数据库接口不允许查询堆叠或在单个函数调用中执行多个查询。如果您尝试堆叠查询,调用会失败,但 SQLite 和 PostgreSQL 会愉快地执行堆叠查询,执行一个字符串中提供的所有查询并造成严重的安全问题。
  • 防止 SQL 注入

    您可以在 PERL 和 PHP 等脚本语言中巧妙地处理所有转义字符。编程语言 PHP 提供的功能string 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 查询引用字符串;检索数据时会导致奇怪的结果。