MySQL SQL注入

  • SQL注入

    如果您通过网页获取用户输入并将其插入到MySQL数据库中,则很有可能会遇到称为SQL 注入的安全问题。本章将教您如何帮助防止这种情况的发生并帮助您保护脚本和MySQL语句。SQL注入通常在您请求用户输入时发生,例如用户名,而不是用户名,而是给您一条MySQL语句,您将在不知不觉中在数据库上运行。永远不要信任用户提供的数据,仅在验证后才处理这些数据;通常,这是通过模式匹配完成的。在以下示例中,用户名被限制为字母数字字符和下划线,并且长度介于8到20个字符之间-根据需要修改这些规则。
    if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
       $result = mysqli_query($conn,"SELECT * FROM users WHERE username = $matches[0]");
    } else  {
       echo "username not accepted";
    }
    为了演示此问题,请考虑以下摘录。
    // supposed input
    $name = "Qadir'; DELETE FROM users;";  //假设这是用户输入,这就危险了
    mysql_query("SELECT * FROM users WHERE name = '{$name}'");
    }
    该函数调用应该从users表中检索一条记录,其中name列与用户指定的名称匹配。通常情况下,$name仅包含字母数字字符,也许还包含空格。但是在这里,通过将一个全新的查询附加到$ name,对数据库的调用变成了一场灾难。注入的DELETE查询将从用户中删除所有记录。幸运的是,如果使用MySQL,则mysqli_query()函数不允许查询堆栈或在单个函数调用中执行多个查询。如果您尝试堆叠查询,则调用将失败。但是,其他PHP数据库扩展(例如SQLitePostgreSQL)可以愉快地执行堆积查询,执行所有以一个字符串提供的查询,并造成严重的安全性问题。
  • 防止SQL注入

    您可以使用PERL和PHP等脚本语言来智能地处理所有转义字符。PHP的MySQL扩展提供了函数mysqli_real_escape_string()来转义MySQL特有的输入字符。
    if (get_magic_quotes_gpc()) {
       $name = stripslashes($name);
    }
    
    $name = mysql_real_escape_string($name);
    mysql_query("SELECT * FROM users WHERE name = '{$name}'");
  • LIKE 查询这么解决

    为了解决LIKE难题,自定义转义机制必须将用户提供的%和_字符转换为文字。使用addcslashes(),该函数可让您指定要转义的字符范围。
    $sub = addcslashes(mysql_real_escape_string("%something_"), "%_");
    // $sub == \%something\_
    mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");