Безопасный вход с уникальным токеном - PullRequest
1 голос
/ 08 февраля 2012

Мой процесс авторизации пользователя выглядит следующим образом.

Во время процесса входа функция запускает следующий код.

 $token = sha1(microtime(true) . mt_rand(10000, 90000));
 setcookie('auth', $token, $timeout);

Затем добавляет сгенерированный token в таблицу базы данных сразу после столбца идентификатора пользователя.Кстати, и в $_SESSION, и в $_COOKIE хранится только значение $token.

Существует другая функция с именем protect, которая находится в верхней части каждой страницы и проверяет, существуют ли файлы cookie:

  1. сначала проверяет таблицу дБ на $token: если с этим токеном нет пользователя, выписывает
  2. Затем проверяет $_SERVER['HTTP_USER_AGENT'], $_SERVER['REMOTE_ADDR'] с теми, которые хранятся в таблицах дБ.

Вопрос

Я чувствую, что это небезопасный способ, потому что, если злоумышленник использует тот же компьютер и тот же браузер, он может получить доступ, просто "скопировав-вставив" куки-файлы.Также $ _SERVER ['REMOTE_ADDR'] не всегда работает.

Как я могу сделать этот вход более безопасным?

Подробно

Вот функция защиты

public function protect() {
    if (!isset($_SESSION)) {
        session_start();
    }
    $data = array();

    if (isset($_SESSION['auth'])) {
        $stmt = $this->db->prepare("SELECT l.browser, l.ip, u.ban from log AS l, users AS u WHERE l.token =? AND u.id=l.user_id LIMIT 1") or die($this->db->error);
        $stmt->bind_param("i", $_SESSION['auth']) or die($stmt->error);
        $stmt->execute() or die($stmt->error);
        $stmt->store_result();
        if ($stmt->num_rows == 0) {
            $this->signout();
        }
        $stmt->bind_result($data['browser'], $data['ip'], $data['ban']);
        $stmt->fetch() or die($stmt->error);
        $stmt->close() or die($stmt->error);
        $this->validation->check("protection", $data);
    } else {
        if (!isset($_COOKIE['auth'])) {
            header('Location:' . wsurl);
        }
        $stmt = $this->db->prepare("SELECT l.browser, l.timeout, l.ip, u.ban from log AS l, users AS u where l.token =? AND u.id=l.user_id LIMIT 1") or die($this->db->error);
        $stmt->bind_param("s", $_COOKIE['auth']) or die($stmt->error);
        $stmt->execute() or die($stmt->error);
        $stmt->store_result();
        if ($stmt->num_rows == 0) {
            $this->signout();
        }
        $stmt->bind_result($data['browser'], $data['timeout'], $data['ip'], $data['ban']) or die($stmt->error);
        $stmt->fetch() or die($stmt->error);
        $this->validation->check("protection", $data);
        session_regenerate_id();
        $_SESSION['auth'] = $_COOKIE['auth'];
        $stmt->close() or die($stmt->error);
    }
}

И проверка проверяет это

if ($data['browser'] != md5($_SERVER['HTTP_USER_AGENT'])) {
            $this->registration->signout();
        }

        if ($data['ban'] == 1) {
            $this->registration->signout(false);
            header('Location:' . wsurl . "?page=msg&id=34");
        }
        if ($data['ip'] != $this->common->getIP("long")) {
            $this->registration->signout();
        }

        if (isset($data['timeout']) && !empty($data['timeout'])) {
            if (($data['timeout'] - $this->common->getTime()) < 0) {
                $this->registration->signout();
            }
        }

Ответы [ 2 ]

4 голосов
/ 08 февраля 2012

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

Честно говоря, это не проблема безопасности, о которой ВЫ должны беспокоиться, это ответственность пользователей.Если кто-то может зайти на свой компьютер и скопировать свои cookie-файлы, он, возможно, предпримет дополнительный шаг для извлечения своих паролей напрямую (легко, если они используют Firefox ..).

1 голос
/ 08 февраля 2012

Возможно, я неправильно понял, но злоумышленник, который может украсть cookie, может украсть сеанс, создав cookie и добавив элементы HTTP_USER_AGENT, REMOTE_ADDR в украденный токен.

Я бы установил токен, и у меня была бы таблица базы данных с

TOKEN    REMOTE_ADDR  HTTP_USER_AGENT
------------------------------------

столбцами.Ваш метод protect () должен проверить токен, а затем сравнить удаленный адрес текущего пользователя и пользовательский агент с базой данных.

Таким образом, злоумышленник, который может украсть ваш файл cookie, также должен иметь возможность имитировать ваш браузер (тривиально) и IP-адрес (намного сложнее, но все же выполнимо).

Также отметьте этот вопрос .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...