你可以请专家给我一些关于这段代码的信息吗?我错过了一些安全漏洞? 你能看到任何潜在的威胁吗?我可以做得更好吗?
我还在学习:)谢谢
<?php
if (isset($_POST['username'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$password2 = mysql_real_escape_string($_POST['password2']);
$encrypted_password = md5($password);
// remove eventuakl space
foreach($_POST as $key => $val) $_POST[$key] = trim($val);
// check if username is taken
$query = mysql_query("SELECT COUNT(*) FROM users WHERE username = '$username'");
if (mysql_result($query, 0) > 0) {
$reg_error[] = 0;
}
// make sure username only cosist of at least 3 letters, numbers or _ -
if (!preg_match('/^[a-zA-Z0-9_-]{3,}$/', $username)) {
$reg_error[] = 4;
}
// check for empty fields
if (empty($username) || empty($password) || empty($password2)) {
$reg_error[] = 2;
}
// check if the passwords match
if ($password != $password2) {
$reg_error[] = 3;
}
// save if error is unset
if (!isset($reg_error)) {
mysql_query("INSERT INTO users (username, password, registered, registration_ip)
VALUES('$username', '$encrypted_password', '".time()."', '".$_SERVER['SERVER_ADDR']."')");
$_SESSION['id'] = mysql_insert_id();
header('refresh: 3; url=/home');
}
}
?>
的login.php
if (isset($_POST['username'])) {
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$md5_password = md5($password);
$query = mysql_query("SELECT id FROM users WHERE username = '$username' and password = '$md5_password'");
if (mysql_num_rows($query) == 0) {
header("Location: ".$_SERVER['REQUEST_URI']."");
exit;
}
// set session
$_SESSION['id'] = mysql_result($query, 0, 'id');
header("Location: /");
exit;
答案 0 :(得分:6)
答案 1 :(得分:3)
我假设您在https上提供此服务,但您没有提及是否这样做 - 如果您不这样做,用户名和密码在明确的网络上进行,这绝对不是很安全。< / p>
存在竞争条件 - 您首先检查用户名是否被占用,然后才能插入。您应该至少使用一个事务,理想情况下只是尝试插入(使用数据库强加的唯一性约束)并在重复的情况下捕获错误。并且,您应该在所有其他健全性检查之后执行此操作,即当您确信自己除了可能的重复之外,注册尝试是正常的。
答案 2 :(得分:3)
由于您没有检查用户名有效性,因此很少bobby tables会给您带来很多麻烦。
答案 3 :(得分:3)
你需要加密密码。
这是放在错误的地方。在使用$ _POST变量之前将它向上移动几行。
// remove eventuakl space
foreach($_POST as $key => $val) $_POST[$key] = trim($val);
您无缘无故地转义密码字段。它们不会被发送到数据库。 md5($ password)将进入数据库并且不会被转义。
编辑:在登录方面,您应该修改注册方面的任何内容。
答案 4 :(得分:1)
您的错误检查无序。我按此顺序进行错误检查:
如果发现错误,请不要继续进一步检查。在最后的INSERT语句中保护每个错误检查,类似于你的守卫。
除了使用mysql_real_escape_string?
之外,您没有对密码字段进行编辑在使用mysql_real_escape_string之前,你应该做mysql_connect。 mysql_real_escape_string将使用该连接来确定连接的字符集。字符集将识别要转义的字符。
答案 5 :(得分:0)
您应该使用参数而不是动态构建您的sql。它将有助于防止SQL注入攻击。小小的桌子可以帮到你。