Что является относительно безопасным способом использования файла cookie для входа?

Мне было интересно, какой самый безопасный способ входа в cookie? Если вы просто храните проход (зашифрованный солью) и имя пользователя в cookie и проверяете его против таблицы пользователя, потенциальный злоумышленник может украсть файл cookie и войти в систему. Обычно люди не проверяют «в последний раз онлайн».

Так есть лучший способ для «помнить меня, печенье»? IP не является хорошим вариантом, не так ли? (Некоторые машины меняют IP все время).

Думаю, я нашел умное решение!

Преимущества этого (сложного?) Скрипта:

  • Когда пользователь успешно войдет в систему с помощью параметра «Запомнить меня», в дополнение к стандартным файлам cookie управления выпуском создается файл cookie для входа. [2]
  • Файл cookie для входа содержит имя пользователя пользователя, идентификатор серии и токен. Серия и токен – это неопровержимые случайные числа из достаточно большого пространства. Все три сохраняются вместе в таблице базы данных.
  • Когда пользователь, не зарегистрированный пользователем, посещает сайт и представляет файл cookie для входа, имя пользователя, серия и токен просматриваются в базе данных.
  • Если триплет присутствует, пользователь считается аутентифицированным. Используемый токен удаляется из базы данных. Создается новый токен, который хранится в базе данных с именем пользователя и идентификатором той же серии, и новый пользовательский файл cookie, содержащий все три, выдается пользователю.
  • Если имя пользователя и серия присутствуют, но токен не совпадает, предполагается кража. Пользователь получает строго сформулированное предупреждение, и все пользовательские сеансы пользователя удаляются.
  • Если имя пользователя и серия отсутствуют, файл cookie для входа игнорируется.

Я создал таблицу в базе данных со следующей информацией:

session | token | username | expire 

Помните, что cookie будет иметь эту настройку:

  $value = "$session|$token|$userhash"; //Total length = 106 
  • Session будет состоять из 40 символов (sha1).
  • Token будет строкой из 32 (md5) символов.
  • Userhash в Userhash cookie будет содержать строку из 32 (md5 из имени пользователя).
  • Username в базе данных будет обычным именем пользователя.
  • Expire будет + 60 дней.

Сценарий:

 if(isset($_SESSION['check']) || $_SESSION['check']){ //User is logged in }else if(isset($_COOKIE['remember']) && strlen($_COOKIE['remember'])==106){ //THERE is a cookie, which is the right length 40session+32token+32user+2'|' //Now lets go check it... conncectdb(); //Sets connection //How do I protect this script form harmful user input? $plode = explode('|',$_COOKIE['remember']); $session = mysql_real_escape_string($plode[0]); $token = mysql_real_escape_string($plode[1]); $userhash = mysql_real_escape_string($plode[2]); $result = mysql_query(" SELECT user FROM tokens WHERE session = '$session' AND token = '$token' AND md5(user) = '$userhash';") if(mysql_num_rows($result)==1){ //COOKIE is completely valid! //Make a new cookie with the same session and another token. $newusername = mysql_result($result,0,0); $newsession = $session; $newtoken = md5(uniqid(rand(), true)); $newuserhash = md5($username); $value = "$newsession|$newtoken|$newuserhash"; $expire = time()+4184000; setcookie('remember', $value, $expire, '/', 'www.example.com', isset($_SERVER["HTTPS"]), true); mysql_query(" UPDATE tokens SET token='$newtoken', expire='$expire' WHERE session = '$session' AND token = '$token' AND md5(user)='$userhash';"); //Set-up the whole session (with user details from database) etc... } else if(mysql_num_rows(mysql_query("SELECT user FROM tokens WHERE session = '$session' AND md5(user) = '$userhash';"))==1)){ //TOKEN is different, session is valid //This user is probably under attack //Put up a warning, and let the user re-validate (login) //Remove the whole session (also the other sessions from this user?) } else { //Cookie expired in database? Unlikely... //Invalid in what way? } } else { //No cookie, rest of the script } 

Преимущества скрипта:

  • Несколько логинов. Вы можете создавать новые сеансы для каждого компьютера, на котором вы находитесь.
  • Cookie и база данных останутся чистыми. Активные пользователи обновляют файлы cookie каждый логин.
  • Проверка сеанса в начале гарантирует, что база данных не получит бесполезных запросов.
  • Если злоумышленник крадет куки-файл, он получает новый токен, но не новый сеанс. Поэтому, когда реальный пользователь посещает веб-сайт со старым (недействительным) токеном, но с действующей комбинацией пользовательского сеанса пользователь получает предупреждение о потенциальной краже. После повторной проверки при входе в новый сеанс создается сеанс, и сеанс, выполняемый злоумышленником, недействителен. Повторная проверка гарантирует, что жертва действительно является жертвой, а не злоумышленником.

Ссылка: http://jaspan.com/improved_persistent_login_cookie_best_practice

Такая функция «помнить меня» всегда является дополнительной угрозой безопасности.

Потому что, как и в сеансе, у вас есть только один идентификатор, который достаточно не только для идентификации пользователя ( кто это? ), Но и для аутентификации этого пользователя ( действительно ли он / она? ) Без фактической аутентификации.

Но в противоположность сеансу, который имеет (или должен иметь) просто короткий срок службы (в основном менее часа), и идентификатор (или должен быть) периодически изменен (зависит от времени и по необходимости из-за изменений состояния / полномочий) , идентификатор «помнить меня» действителен в течение нескольких дней, если даже не месяцы или годы! И этот длительный срок действия представляет собой дополнительный риск для безопасности.

Поэтому перед тем, как спросить, как реализовать такую ​​функцию «помнить меня», вы должны спросить себя, действительно ли вы хотите получить дополнительную угрозу безопасности. Это зависит главным образом от активов, которые имеет ваше приложение, и какова цель аутентификации, и если вы хотите рискнуть олицетворениями / кражи личных данных, которые представляют функция «запомнить меня».

Если это так, убедитесь, что вы обеспечиваете базовую безопасность с помощью HTTPS и устанавливаете флаг HTTPOnly и безопасный флаг в своих файлах cookie . Затем вы можете сделать следующее, чтобы создать такую ​​функцию «запомнить меня»:

  • Запрос на аутентификацию
    Если пользователь прошел аутентификацию через HTTPS и установил опцию «запомнить меня», сгенерируйте случайный запоминающий токен, сохраните его на стороне сервера в базе данных «запомнить меня» и установите для меня куки-файл с сохраненным флагом с этим значением. Затем запустите новый сеанс и установите флаг « Запомнить меня» .

  • Любой другой запрос

    1. Если текущий сеанс отсутствует, перенаправляйте на страницу « запомнить меня» через HTTPS, которая проверяет, есть ли у меня куки-файл. Если есть токен, который я помню, он действителен, недействителен, генерирует новый, сохраняет его в базе данных «запомнить меня», устанавливает cookie с этим новым токеном и создает новый сеанс с установленным флажком « запомнить меня» . В противном случае перенаправление на страницу входа.
    2. Если текущий сеанс недействителен (обязательно используйте строгое недействительность сеанса ), перенаправляйте на страницу « запомнить меня» через HTTPS, если установлен флаг « Запомнить меня» ; в противном случае перенаправить на страницу входа.

При этом аутентификация обеспечивается посредством HTTPS, как первоначальной аутентификации, так и аутентификации «запомнить меня». И пользователь является подлинным только в течение текущего сеанса; если он истекает, пользователь должен повторно аутентифицироваться либо с помощью токена « запомнить меня», либо с помощью его учетных данных. И поскольку помните, что токены хранятся в базе данных, пользователь может аннулировать любой существующий памятный токен.

Самые популярные способы:

  • Многие сценарии используют какое-то отслеживание сеанса. Когда пользователь впервые посещает веб-сайт, он генерирует уникальный случайный идентификатор для пользователя и сохраняет информацию о сеансе на сервере и идентификатор в файле cookie . Затем сервер идентифицирует пользователя, используя уникальный идентификатор (называемый идентификатором сеанса). Информация, связанная с идентификатором сеанса, может быть видна только сервером. PHP использует это по умолчанию,

  • Некоторые хранят пользовательские данные в самом файле cookie, но с сигнатурой HMAC, используя секретную строку в качестве ключа. Сценарий отбрасывает файл cookie, если подпись не соответствует. Таким образом, сервер не должен сохранять данные сеанса на сервере . Пользователь видит, что находится в сеансе, просматривая файл cookie, поэтому вы не должны хранить в нем конфиденциальные данные. Должно быть достаточно только идентификатора пользователя (и, возможно, времени входа в систему и времени истечения срока действия cookie). Хотя пользователь может видеть, что находится в информации о сеансе, подпись в файле cookie гарантирует, что пользователь не может самостоятельно изменить данные сеанса.

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

Если вы действительно обеспокоены безопасностью, используйте HTTPS .

Также прочитайте эту статью , особенно раздел « Как работают веб-сайты»?