我收到此错误,我不太明白为什么。我现在已经花了好几个小时了,尝试通过研究调查,没有运气。
在我的PHP登录系统中,我检查是否选择了行:
//Start session
session_start();
//Include database connection details
require_once('config.php');
//Array to store validation errors
$errmsg_arr = array();
//Validation error flag
$errflag = false;
//Connect to mysql server
$link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
if(!$link) {
die('Failed to connect to server: ' . mysql_error());
}
//Select database
$db = mysql_select_db(DB_DATABASE);
if(!$db) {
die("Unable to select database");
}
//Prevent SQL injection.
function clean($str) {
$str = @trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
//Sanitize the POST values
$login = clean($_POST['login']);
$password = clean($_POST['password']);
//Input Validations
if($login == '') {
$errmsg_arr[] = 'Login ID missing';
$errflag = true;
}
if($password == '') {
$errmsg_arr[] = 'Password missing';
$errflag = true;
}
//If there are input validations, redirect back to the login form
if($errflag) {
$_SESSION['ERRMSG_ARR'] = $errmsg_arr;
session_write_close();
echo "input validation";
exit();
}
//Create query
$qry="SELECT * FROM details WHERE USERNAME='$login' AND PASSWORD='".md5($_POST['password'])."'";
$result=mysql_query($qry);
//Check whether the query was successful or not
if($result) {
if(mysql_num_rows($result) == 1) {
//Login Successful
session_regenerate_id();
$member = mysql_fetch_assoc($result);
$_SESSION['MEMBER_ID'] = $member['USERNAME'];
session_write_close();
header("location: client-index.php");
exit();
}else {
//Login failed
echo "login failed?";
exit();
}
}else {
die("Query failed");
}
?>
无论出于何种原因,它都会“失败”。
答案 0 :(得分:1)
如果你告诉我们错误是什么,它可能会帮助我们更好地回答你的问题。
但无论如何,这显然是错误的方式。这个系统存在许多严重的问题。
首先,你没有消毒你的输入。由于您将数据和命令混合在一起,用户所要做的就是输入用户名“x”或1 = 1' - “进入系统。原因如下:SQL服务器将获得的唯一命令是“SELECT * FROM details WHERE USERNAME ='x'或1 = 1”。换句话说,如果用户名是x或1 = 1(它是),那么SQL服务器将以肯定的结果作出响应。 (“username”末尾的两个破折号表示SQL中的注释,因此查询中的所有内容都将被忽略)。
真正的恶意攻击者甚至可以通过输入用户名“x' - ; DROP TABLES;'来破坏您的系统,并且您的整个数据库都将消失。(请参阅this comic了解我的位置。 )
事实上,你根本不应该真正使用mysql_query。根据{{3}}:
不鼓励使用此扩展程序。相反,应该使用MySQLi或PDO_MySQL扩展。
如果我是你,我会更多地阅读这个主题。即使这只是为了练习,它仍然是最好的第一次正确的事情。看看PHP documentation:它不是很难学,但却非常有用。它的主要优点是它不会混合数据和命令,因此您不会遇到同样的问题,即未经过抽样的输入会弄乱您的数据库。
此外,虽然很高兴看到您正在对您的密码进行哈希处理 - 而且您会惊讶于有多少公司应该知道更好 - MD5不再被认为是加密安全的。获得所谓的“哈希冲突”相对容易,其中两个不同的明文产生相同的哈希。现在,SHA-256应该是您使用的最小值。
另外,关于哈希的问题,你应该添加一些叫盐的东西。 salt是您添加到明文中的某种随机文本,以便进一步模糊它。这样做的原因是那里有所谓的彩虹表。彩虹表是所有常用密码的预先计算的哈希列表。如果有人要抓住你的数据库,他们就可以将所有密码与彩虹表进行比较,以找到他们的明文。
最后,为了减缓暴力攻击 - 攻击者尝试所有字母数字组合直到他们获得密码 - 你也应该使用一个循环,其中哈希算法被重新计算x次,通常1000到10000次之间。 PHP的PDO做得非常好。
顺便说一下:不要心疼。我之前也做过所有这些事情。这就是我知道你不应该这样做的原因。别担心 - 你很快就会到达那里。坚持下去!
答案 1 :(得分:1)
我是网站的新手,所以无法添加评论,也许这不会有多大帮助,但不管怎么说还是不好意思
在你的SQL查询中,它看起来像是将变量$ login作为文本传递而不是变量值
$qry="SELECT * FROM details WHERE USERNAME='$login' AND PASSWORD='".md5($_POST['password'])."'";
它应该是
$qry="SELECT * FROM details WHERE USERNAME=".$login." AND PASSWORD='".md5($_POST['password'])."'";
答案 2 :(得分:1)
是查询失败还是登录失败?
无论如何查询失败: 尝试将您的查询更改为: 用反引号围绕你的领域(不是单引号)
$qry="SELECT * FROM details WHERE `USERNAME`='$login' AND `PASSWORD`='".md5($_POST['password'])."'";
如果登录失败:
if(mysql_num_rows($result) == 1) {
//Login successful
}else {
//Login failed
}
你确定查询只有1个结果吗?因为在这种情况下,如果结果大于1,它也将无法登录。