Каков эффективный способ защитить переменную сеанса в php? - PullRequest
4 голосов
/ 27 января 2010

Мое веб-приложение использует UserId почти во всем приложении.

  • Какой самый эффективный способ защитить переменную сеанса в php?

  • Является ли сеанс уязвимым для атак?

  • Должен ли я хранить зашифрованное значение UserId в сеансе?

Любое предложение ...

1 Ответ

17 голосов
/ 27 января 2010

Примечание: Взято из моего предыдущего ответа .

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

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

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

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

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

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');
}

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

Другая стратегия заключается в повороте 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 скомпрометирован, вы в значительной степени готовы.Вышеприведенные стратегии являются всего лишь мерой отсрочки.

...