这是否容易受到SQL注入的攻击?


Is this vulnerable to SQL injection

我知道关于这个已经有很多问题了。但我的方法和他们的不一样,所以我想知道。我想我理解SQL,但我不想在未来犯错误的风险,所以感谢任何帮助。(这只是我在做的一个项目,不是作业或任何重要的事情)。

function checkLogin($username, $password) {
    $username = strtolower($username);
    connectToDatabase();
    $result = mysql_query("SELECT * FROM `users` WHERE username='$username'");
    $dbpassword = "";
while($row = mysql_fetch_array($result))
  {
    $rowuser = $row['username'];
  if($username != $row['username']) continue;
  $dbpassword = $row['password'];
  }
    if($dbpassword == "") {
        return false;
    }
    $genpass = generatePassword($password);
   return $genpass == $dbpassword;
}

所以用你最好的镜头打我吧:)我认为我的方法并没有达到应有的效率。我不太懂php,无法理解$row = mysql_fetch_array($result)在做什么。

由于您将任意字符串直接放入SQL语句中,因此很容易受到SQL注入的攻击。

(编辑基于下面的评论。)

SQL注入的典型例子是创建一个用户名,如下所示:
Robert'); DROP TABLE users;--

必选XKCD链接

解释:

给定上面的"username",插入到字符串中会得到:

SELECT * FROM `users` WHERE username='Robert'); DROP TABLE users;--'

结尾的注释符号--需要"摆脱"您的闭引号,因为我刚刚替换了我的一个来结束您的select语句,以便我可以注入DROP TABLE语句。

正如@sarnold指出的,PHP的mysql_query只执行字符串中的第一个查询,所以上面的例子(称为查询堆叠)不适用。函数解释如下:http://php.net/manual/en/function.mysql-query.php.

在这里可以找到一个更好的例子。这里他们使用用户名

' OR 1 OR username = '

插入后变成

SELECT * FROM `users` WHERE username='' OR 1 OR username = ''

,这会导致应用程序检索所有用户。

简短的回答是肯定的。

一个可能更有用的答案是,你永远不应该相信用户输入;如果有可用的PDO,则预处理语句是防止这种情况发生的最简单方法。参见PDO预处理语句

<?php
$stmt = $dbh->prepare("SELECT * FROM `users` WHERE username=?");
if ($stmt->execute($username)) {
  while ($row = $stmt->fetch()) {
    print_r($row);
  }
}
?>

其他的答案是一个很好的描述你的问题,然而,我认为他们都忽略了最好的解决方案:使用PHP的PDO准备语句的查询。

$stmt = $dbh->prepare("SELECT * FROM users where username = ?");
if ($stmt->execute(array($username))) {
  while ($row = $stmt->fetch()) {
    print_r($row);
  }
}

这是一个小而简单的例子。使用PDO还有更复杂的方法,它们可能更适合您的应用程序。

当您使用PDO准备语句时,您永远不需要手动转义任何内容,只要您使用这种稍微不同的风格,您就永远不会编写SQL注入漏洞您不必为每个底层"数据"维护两个变量—一个经过处理,一个作为用户提供—因为只需要一个。

我会说是的,它是开放的SQL注入。

这是因为您以$username的形式接收用户输入,并将其放入SQL语句中,而没有确保它是干净的。

我喜欢在我的应用程序中使用这个函数来清理字符串:

function escape($data) {
    $magicQuotes = get_magic_quotes_gpc();
    if(function_exists('mysql_real_escape_string')) {
        if($magicQuotes) {
            $data = stripslashes($data);
        }
        $data = mysql_real_escape_string($data);
    }
    else {
        if(!$magicQuotes) {
            $data = addslashes($data);
        }
    }
    return $data;
}

那么你可以这样使用:

$username = escape(strtolower($username));
connectToDatabase();
$result = mysql_query("SELECT * FROM `users` WHERE username='$username'");