这容易受到SQL注入的影响

时间:2011-10-22 06:38:35

标签: php sql code-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)正在做什么。

4 个答案:

答案 0 :(得分:6)

因为您正在使用任意字符串并将其直接放入SQL语句中,所以您很容易受到SQL注入。

已编辑基于以下评论。)

SQL注入的典型示例是创建一个用户名,如下所示:

Robert'); DROP TABLE users;--

Obligatory XKCD link

说明:

鉴于上面的“用户名”,插入字符串会导致:

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

最后的评论符号--需要“摆脱”你的结束语,因为我只是替换了我的一个结束你的选择语句以便我可以注入DROP TABLE语句。

正如@sarnold所指出的,PHP的mysql_query只执行字符串中的第一个查询,因此上面的示例(称为 query stacking )不适用。这里解释了这个功能:http://php.net/manual/en/function.mysql-query.php

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

' OR 1 OR username = '
插值的

变为

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

会导致您的应用程序检索所有用户。

答案 1 :(得分:4)

简短的回答是肯定的。

或许更有帮助的答案是你永远不要相信用户输入;如果您有可用的PDO,准备好的语句是防止这种情况的最简单方法。见PDO Prepared Statements

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

答案 2 :(得分:4)

其他答案是对您的问题的精彩描述,但是,我认为他们都忽略了最佳解决方案:使用PHP的PDO Prepared Statements进行查询。

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

这是一个简单的小例子。有更复杂的方法可以更好地适应您的应用程序。

当您使用PDO预处理语句时,您永远不需要手动转义任何内容,只要您使用这种稍微不同的样式,您就永远不会编写SQL注入漏洞您无需维护每个底层“数据”有两个变量 - 一个是消毒的,一个是用户提供的 - 因为只需要一个。

答案 3 :(得分:2)

我会说是的,它对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'");