Мои пользователи вышли из моего сайта. Это происходит, когда кто-то входит в систему с другого устройства. Я заглянул в него и заметил, что кто-то с удаленного IP-адреса смог войти на мой сайт как разные пользователи.
Я не знаю, намеренно ли я являюсь целью или это какая-то ошибка в моем коде. Я хотел бы знать, как правильно настроить сеансовые куки-файлы безопасным способом, чтобы этого не происходило.
Мои файлы cookie - только HTTP
Я также не верю, что это атака «человек посередине», поскольку несколько пользователей из разных областей выходят из системы . Мой сайт защищен SSL.
Я не верю, что это атака грубой силой. Иногда, когда я вхожу, в течение 30 секунд, я снова выхожу из системы , а удаленный IP-адрес регистрируется.
Я не верю, что у него есть доступ к каким-либо паролям. Все хешируется в базе данных , и единственное, что хранится на клиенте, это HTTP-токен сеанса HTTP ONLY.
Я очень застрял.
Вот мой скрипт входа в систему , который проверяет учетные данные пользователя и устанавливает сеанс:
//database connection is $db_connect
//Creates a random String
function generateRandomString() {
$length = rand(25, 30);
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
//Grab email, password, IP address
$email_attempt=strtoupper(preg_replace('#[^a-z0-9\.\@\_\-\+]#i', '', $_POST['e']));
$password_attempt=$_POST["p"];
$user_IP = preg_replace('#[^0-9.\:]#', '', getenv('REMOTE_ADDR'));
//Call the database
$sql = "SELECT password, userID FROM user_data WHERE email='$email_attempt' LIMIT 1";
$query = mysqli_query($db_connect, $sql);
if(mysqli_num_rows($query)>0)
{
//Get the ID and hashed password from database
while($row = $query->fetch_assoc()) {
$password_db=$row["password"];
$userID_db=$row["userID"];
}
//Verify Login using password verify
if(password_verify($password_attempt, $password_db)==true){
//remove any previous sessions for the user
$sql = "DELETE FROM user_sessions WHERE userID='$userID_db'";
$query = mysqli_query($db_connect, $sql);
//Clear any current cookies from client
if(isset($_COOKIE["user"]) && isset($_COOKIE["token"])) {
setcookie("user", '', strtotime( '-5 days' ), '/');
setcookie("token", '', strtotime( '-5 days' ), '/');
}
session_destroy();
// Set Session data to an empty array
$_SESSION = array();
//create a new token, set new session and cookies
$token=generateRandomString();
$_SESSION['user'] = $userID_db;
$_SESSION['token'] = $token;
setcookie("user", $userID_db, strtotime( '+3 days' ), "/", "", "", TRUE);
setcookie("token", $token, strtotime( '+3 days' ), "/", "", "", TRUE);
//Hash the token to store in the database
$token_hash=password_hash($token, PASSWORD_DEFAULT);
//Store session into database
$sql = "INSERT INTO user_sessions
(userID, session_token, IP, loginDate)
VALUES
('$userID_db','$token_hash','$user_IP', '$current_date')";
$query = mysqli_query($db_connect, $sql);
header("Location: dashboard.php");
}
else
{
echo 'wrong_credentials';
}
}
Вот мой код, чтобы оценить пользователя и посмотреть, вошли ли они в систему, изучив сеанс и файлы cookie;
//start session
session_start();
$user_ok = false;
$clientID = "";
$token = "";
$user_IP = preg_replace('#[^0-9.\:]#', '', getenv('REMOTE_ADDR'));
if(isset($_SESSION["user"]) && isset($_SESSION["token"])) {
//Get session
$clientID = preg_replace('#[^a-z0-9]#i', '', $_SESSION['user']);
$token = preg_replace('#[^a-z0-9]#i', '', $_SESSION['token']);
// Verify the user with session data
$user_ok = checkUser($db_connect,$clientID,$token,$user_IP);
} else if(isset($_COOKIE["user"]) && isset($_COOKIE["token"])){
//Set session from cookie
$_SESSION['user'] = preg_replace('#[^a-z0-9]#i', '', $_COOKIE['user']);
$_SESSION['token'] = preg_replace('#[^a-z0-9]#i', '', $_COOKIE['token']);
//Get session data
$clientID = preg_replace('#[^a-z0-9]#i', '', $_SESSION['user']);;
$token = preg_replace('#[^a-z0-9]#i', '', $_SESSION['token']);
// Verify the user
$user_ok = checkUser($db_connect,$clientID,$token,$user_IP);
}
// User Verify function
function checkUser($db_connect,$user,$token,$ip){
//Grab the session
$sql = "SELECT session_token FROM user_sessions WHERE userID='$user' AND ip='$ip' LIMIT 1";
$query = mysqli_query($db_connect, $sql);
if(mysqli_num_rows($query)>0){
$row=mysqli_fetch_row($query);
$token_hashed=$row[0];
//compare token given and hashed token
if(password_verify($token,$token_hashed)==true)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
Итак, мой вопрос: достаточно ли безопасен этот код?
Как я могу быть более безопасным?
Также, если у вас есть представление о том, что происходит в этой головоломке, пожалуйста, дайте мне знать, так как я получаю уничтожено . Заранее спасибо.