Системы на PHP логин


Я есть php система входа на основе файлов cookie на моем сайте, используя ниже приведенный код. Я хочу знать, что будет ли этот логин система является безопасной или нет, он может быть взломан в любом случае?

<?php
session_start();
if(isset($_SESSION["userid"]))
{
 header("location:index.php");
}
include( $_SERVER['DOCUMENT_ROOT'] . '/conndb.php' );

if(isset($_POST["login"]))   
{  
 if(!empty($_POST["member_name"]) && !empty($_POST["member_password"]))
 {
  $name = mysqli_real_escape_string($conn, $_POST["member_name"]);
  $password = mysqli_real_escape_string($conn, $_POST["member_password"]);
$stmt_check = $conn->prepare("SELECT * FROM userz WHERE email =? AND pass = ? AND active ='1'");
$stmt_check->bind_param("ss", $name, $password);
$stmt_check->execute();
$stmt_check->store_result();
$numberofrows = $stmt_check->num_rows;

if(($numberofrows) > 0){

    setcookie ("member_login",$name,time()+ (10 * 365 * 24 * 60 * 60));  
    setcookie ("member_password",$password,time()+ (10 * 365 * 24 * 60 * 60));
    $_SESSION["userid"] = $name;
   header("location:index.php"); 

} else {

   $message = "Invalid Login OR Email not Verified";  
}

$stmt_check->close();

 }
 else
 {
  $message = "Both are Required Fields";
 }
}  
?>

Кроме того этот код, ниже фрагмент кода на каждой странице, чтобы проверить, является ли пользователь уже вошел в систему или нет.

 <?php
    session_start(); 
    if (empty($_SESSION['userid'])) {
        header('Location: users/login.php');
        exit;
    }
    ?>


184
1
задан 2 февраля 2018 в 03:02 Источник Поделиться
Комментарии
1 ответ

В комментариях уже сказали, написание систем надежно очень сложно. Я бы настоятельно рекомендуем использовать существующую систему, как один из тех, Кико программного обеспечения поместил в своем комментарии. С этой оговоркой из пути, давайте взглянем на код.


<?php
session_start();
if(isset($_SESSION["userid"]))
{
header("location:index.php");
}

Любое время вы используете редирект, он должен быть немедленно последовал выход(). Если вы не сделаете этого остальная часть кода будет по-прежнему выполняться, и если браузер пользователя не учитывает расположение заголовка, они могут посмотреть остальные страницы. Тут не так плохо, но может привести к неприятным проблемам управления доступом. HTTP-заголовки, как правило, капитализируются с пробелом после двоеточия, как Location: /index.php но я не думаю, что есть любой (всего) браузер, что бы жаловаться на это.

if(isset($_POST["login"]))   
{
if(!empty($_POST["member_name"]) && !empty($_POST["member_password"]))

Пользователь может отправить массив здесь имя пользователя или пароль, а не строку, которую вы, наверное, не хотите, как некоторые PHP функции делают странные вещи с массивами. Если вы хотите только строки, вы должны проверить его здесь.

 {
$name = mysqli_real_escape_string($conn, $_POST["member_name"]);
$password = mysqli_real_escape_string($conn, $_POST["member_password"]);

В mysql_real_escape_string() функция имеет некоторые проблемы с некоторыми кодировками, поэтому вы должны быть осторожны с ним. Но поскольку вы используете подготовленные операторы, вам не нужно, чтобы избежать этих, и в самом деле, если вы убежать от них и у них есть определенные символы, такие как одинарные кавычки, вы будете в конечном итоге с неправильным ценностям.

$stmt_check = $conn->prepare("SELECT * FROM userz WHERE email =? AND pass = ? AND active ='1'");

Это active строки? Я ожидаю, что это будет целое число (или даже логическое), но у вас одинарные кавычки вокруг 1, поэтому к нему относились как строку в MySQL.

Делать SELECT * обычно плохой знак - вы должны выбрать только столбцы, которые вам действительно нужны (которые не как в этом случае, вы, вероятно, может уйти с графом).

Как уже упоминалось в комментариях, хранить пароли в виде обычного текста-это очень плохая идея. Вы должны использовать безопасные функции хэширования, как bcrypt/scrypt в/PBKDF2 для хранения паролей.

$stmt_check->bind_param("ss", $name, $password);
$stmt_check->execute();
$stmt_check->store_result();
$numberofrows = $stmt_check->num_rows;
if(($numberofrows) > 0){

Может количество строк не вернулся более чем на 1? Это будет означать, что у вас есть дубликаты пользователей в вашей базе данных, который будет знаком что-то пошло ужасно неправильно. Если есть что-то очень странное в базе данных, это было бы лучше, чтобы проверить, что именно 1 ряд был возвращен.

setcookie ("member_login",$name,time()+ (10 * 365 * 24 * 60 * 60));  
setcookie ("member_password",$password,time()+ (10 * 365 * 24 * 60 * 60));

Хранить незашифрованный пароль (или пароль) в cookie-это очень плохая идея, особенно если он будет храниться в течение десяти лет. Любые куки, которые вы создаете, должны быть также помечены как HttpOnly, безопасной (предполагая, что вы используете SSL, который вы действительно должны быть), и при необходимости SameSite.

$_SESSION["userid"] = $name;

Это хорошо, чтобы быть внутренне согласованным с именами переменных. Пока же информация была названа member_name, имя, email и userId

header("location:index.php");

Смотрите комментарии на предыдущее header() использование.

} else {
$message = "Invalid Login OR Email not Verified";
}

$stmt_check->close();

Это может быть закрыт ранее, сразу после того как вы получите число строк.


В качестве программного обеспечения Кико упомянул в своем первом комментарии, есть также некоторые другие функции безопасности, которых не хватает:


  • Блокировка учетной записи

  • Капчи или другой защиты от атак методом подбора

  • Угон сессии

Написание кода проверки подлинности очень сложно, и если вы решите все эти вопросы, есть еще все виды других сложностей, как сроки нападения, перечисление пользователей, и т. д. Ты гораздо лучше позволить кому-то жить с этой болью.

1
ответ дан 22 февраля 2018 в 08:02 Источник Поделиться