我意识到已经存在很多关于此的问题。但我的方法和他们的方法不一样,所以我想知道。我想我理解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)
正在做什么。
答案 0 :(得分:6)
因为您正在使用任意字符串并将其直接放入SQL语句中,所以您很容易受到SQL注入。
(已编辑基于以下评论。)
SQL注入的典型示例是创建一个用户名,如下所示:
Robert'); DROP TABLE users;--
说明:
鉴于上面的“用户名”,插入字符串会导致:
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'");