Что мне нужно хранить в сеансе php, когда пользователь вошел в систему? - PullRequest
18 голосов
/ 03 августа 2009

В настоящее время, когда пользователь вошел в систему, я создал 2 сеанса.

$_SESSION['logged_in'] = 1;
$_SESSION['username']  = $username; // user's name

Так что, те страницы, которые требуют авторизации, я просто делаю так:

if(isset($_SESSION['logged_id'])){
// Do whatever I want
}

Есть ли лазейки безопасности? Я имею в виду, легко ли взломать мою сессию? Как люди взламывают сессию? и как мне это предотвратить ??

EDIT:

Только что нашел это:

http://www.xrvel.com/post/353/programming/make-a-secure-session-login-script

http://net.tutsplus.com/tutorials/php/secure-your-forms-with-form-keys/

Только что нашел ссылки, достаточно ли хороши эти методы ?? Пожалуйста, дайте свое мнение. Я до сих пор не получил лучший ответ.

Ответы [ 9 ]

45 голосов
/ 04 августа 2009

Терминология

  • Пользователь: Посетитель.
  • Клиент: Определенное веб-совместимое программное обеспечение, установленное на конкретном компьютере.

Понимание сеансов

Чтобы понять, как сделать сеанс безопасным, вы должны сначала понять, как сеансы работают.

Давайте посмотрим на этот кусок кода:

session_start();

Как только вы позвоните, PHP будет искать файл cookie с именем PHPSESSID (по умолчанию). Если он не найден, он создаст его:

PHPSESSID=h8p6eoh3djplmnum2f696e4vq3

Если он найден, он принимает значение PHPSESSID и затем загружает соответствующий сеанс. Это значение называется session_id.

Это единственное, что клиент узнает. Все, что вы добавляете в переменную сеанса, остается на сервере и никогда не передается клиенту. Эта переменная не изменится, если вы измените содержимое $_SESSION. Он всегда остается неизменным, пока вы не уничтожите его или не истечет время ожидания. Следовательно, бесполезно пытаться запутать содержимое $_SESSION путем его хеширования или другими способами, поскольку клиент никогда не получает и не отправляет эту информацию.

Затем, в случае нового сеанса, вы установите переменные:

$_SESSION['user'] = 'someuser';

Клиент никогда не увидит эту информацию.


Проблема

Проблема безопасности может возникнуть, когда злоумышленник крадет session_id другого пользователя. Без какой-либо проверки он сможет выдать себя за этого пользователя. Нам нужно найти способ уникальной идентификации клиента (а не пользователя).

Одна стратегия (наиболее эффективная) включает проверку, совпадает ли IP-адрес клиента, начавшего сеанс, с IP-адресом лица, использующего сеанс.

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}

// The Check on subsequent load
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) {
    die('Session MAY have been hijacked');
}

Проблема этой стратегии заключается в том, что если клиент использует балансировщик нагрузки или (при длительной сессии) пользователь имеет динамический IP-адрес, он вызовет ложное предупреждение.

Другая стратегия включает проверку пользовательского агента клиента:

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
}

// The Check on subsequent load
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) {
    die('Session MAY have been hijacked');
}

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

Другая стратегия - вращать session_id на каждые 5 запросов. Таким образом, теоретически session_id не остается достаточно долго, чтобы его можно было похитить.

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['count'] = 5;
}

// The Check on subsequent load
if(($_SESSION['count'] -= 1) == 0) {
    session_regenerate_id();
    $_SESSION['count'] = 5;
}

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

К сожалению, ни одно решение не является надежным. Если ваш session_id скомпрометирован, вы в значительной степени готовы. Вышеуказанные стратегии являются всего лишь мерой отсрочки.

13 голосов
/ 03 августа 2009

Это смешно.

Перехват сеанса происходит, когда (обычно через межсайтовую скриптовую атаку) кто-то перехватывает ваш sessionId (файл cookie, автоматически отправляемый на веб-сервер браузером).

Кто-то опубликовал это, например:

Итак, когда пользователь входит в систему:

// не самый безопасный хеш! $ _SESSION ['checkum'] = md5 ($ _ SESSION [ 'имя пользователя'] $ соль.);

А перед входом в чувствительную зону:

if (md5 ($ _ SESSION ['username']. $ Salt) ! = $ _SESSION ['контрольная сумма']) {
handleSessionError (); }

Давайте рассмотрим, что не так с этим

  1. Соли - не так, но бессмысленно. Никто не взломает твой проклятый md5, кому какое дело, если он соленый
  2. сравнение md5 переменной SESSION с md5 той же переменной, хранящейся в SESSION - вы сравниваете сеанс с сеансом. Если вещь будет похищена, это ничего не даст.
$_SESSION['logged_in'] = 1;
$_SESSION['username']  = $username; // user's name
$_SESSION['hash']      = md5($YOUR_SALT.$username.$_SERVER['HTTP_USER_AGENT']);

// имя пользователя хэшируется, чтобы избежать манипуляция

Избегать манипуляций кем? волшебная сессия фей? Ваши переменные сеанса не будут изменены, если ваш сервер не будет скомпрометирован. Хеш действительно нужен только для того, чтобы красиво сконденсировать вашу строку в строку из 48 символов (пользовательские агенты могут быть немного длиннее).

По крайней мере, теперь мы проверяем некоторые данные клиента, вместо того, чтобы проверять данные SESSION - SESSION, они проверили HTTP_USER_AGENT (это строка, идентифицирующая браузер), этого будет более чем достаточно для защиты вас, но вы Я должен понимать, что если человек уже каким-то образом принял ваш sessionId, есть вероятность, что вы также отправили запрос на сервер плохих парней и передали плохому парню свой пользовательский агент, поэтому умный хакер подделает ваш пользовательский агент и защитит эту защиту. .

Что вы узнали о грустной правде.

Как только ваш идентификатор сессии скомпрометирован, вы ушли. Вы можете проверить удаленный адрес запроса и убедиться, что он остается неизменным во всех запросах (как я), и это будет отлично работать для 99% вашей клиентской базы. Затем однажды вам позвонит пользователь, который использует сеть с прокси-серверами со сбалансированной нагрузкой, отсюда будут поступать запросы через группу разных IP-адресов (иногда даже в неправильной сети), и он потеряет свой сессия слева направо и в центре.

1 голос
/ 04 августа 2009

Чтобы предотвратить фиксацию сеанса, которая заключается в угадывании SID или краже его различными способами. Неважно, насколько изощренна ваша логика сеанса, она определенно будет уязвима для кражи в некоторой степени. Вот почему вы должны восстанавливать идентификатор каждый раз, когда вы делаете что-то важное. Например, если вы собираетесь сделать сообщение или изменить настройку в администраторе, сначала запустите session-Регенерат-ID. Затем хакер должен снова пройти через процесс взлома. Это в основном дает хакеру одноразовый снимок с идентификатором, за который он потратил все время.

http://us.php.net/manual/en/function.session-regenerate-id.php

Или вы можете менять идентификатор каждый раз, когда

if ($ _ SESSION ['counter'] == 3) {session_regenerate_id (); $ _ SESSION ['counter'] == 0}

Кроме того, $ _SERVER ['HTTP_USER_AGENT'] не очень надежен. Старайтесь избегать этого не только по этой причине, но и потому, что это удобно для хакеров, поскольку они знают, что агенты широко используются для этого. Вместо этого попробуйте использовать $ _SESSION ['id_token'] = sha1 (некоторая сумасшедшая информация, такая как память файла, имя файла, время).

1 голос
/ 03 августа 2009

Полагаю, второй должен быть 'logged_in'?

Некоторые ресурсы, касающиеся безопасности сеанса:

phpsec

Шифлетт

1 голос
/ 03 августа 2009

Вы можете сохранить IP-адрес, подпись браузера и т. Д., Чтобы идентифицировать пользователя. При каждом запросе сверяйте его с текущими значениями, чтобы увидеть, произошло ли что-нибудь подозрительное.

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

1 голос
/ 03 августа 2009

Вы можете украсть сессии через javascript (XSS-> межсайтовая скриптовая атака). Вы всегда должны использовать соленый MD5 Hash для защиты вашего сеанса.

Чтобы избежать перехвата сеанса, вы должны установить пользовательский агент

$ _ SERVER [ 'HTTP_USER_AGENT']

в хеш.

В вашем примере:

$_SESSION['logged_in'] = 1;
$_SESSION['username']  = $username; // user's name
$_SESSION['hash']      = md5($YOUR_SALT.$username.$_SERVER['HTTP_USER_AGENT']); // user's name hashed to avoid manipulation

Перед использованием сеанса убедитесь, что он использует правильный хеш:

if (!$_SESSION['hash']==md5($YOUR_SALT.$username.$_SERVER['HTTP_USER_AGENT'])){
  die ('session hash not corrected')
}
1 голос
/ 03 августа 2009

Руководство по безопасности сеансов в PHP можно найти здесь .

0 голосов
/ 09 августа 2009

Когда я столкнулся с этой проблемой при сборке SugarCRM, я отслеживал и проверял IP-адрес пользователя (в дополнение к некоторым другим вещам). Я сравнил только первые три раздела IP-адреса. Это позволило для большинства локально переменных IP-адресов. Я также сделал возможным отключить проверку IP-адреса для установок, где распространены значительные различия в IP-адресе. Я думаю, что только сравнение начала IP-адреса поможет вам с безопасностью, не добавляя такого серьезного ограничения в ваше приложение.

Пример: "###. ###. ### .---" Будет проверена только часть IP-адреса, отмеченная знаком «#».

192.168.1.101
192.168.1.102
192.168.1.XXX

Все считаются равными.

Jacob

0 голосов
/ 03 августа 2009

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

Итак, когда пользователь входит в систему:

// not the most secure hash!
$_SESSION['checksum'] = md5($_SESSION['username'].$salt); 

А перед входом в чувствительную зону:

if (md5($_SESSION['username'].$salt) != $_SESSION['checksum'])
{
  handleSessionError();
}

По умолчанию сеансы часто хранятся в виде файлов на стороне сервера, и в браузер пользователя помещается cookie-файл, чтобы запомнить, к какому файлу обращаться. Когда дело доходит до взлома сеанса, хакер каким-то образом извлекает достаточно информации, чтобы дублировать вход в систему, или сумел изменить данные сеанса, используя информацию из cookie.

Вы можете закодировать свою собственную обработку сессий, используя базы данных для дополнительной безопасности. Некоторые более строгие CMS, такие как Joomla, также регистрируют IP. Тем не менее, это вызывает проблемы у людей, использующих определенный ISP

...