PHP Session Security

Каковы некоторые рекомендации по поддержанию ответственной безопасности сеанса с помощью PHP? В интернете есть информация, и пришло время приземлиться в одном месте!

2.08.2008 02:41:34
13 ОТВЕТОВ
РЕШЕНИЕ

Есть несколько вещей, чтобы сохранить ваш сеанс в безопасности:

  1. Используйте SSL при аутентификации пользователей или выполнении конфиденциальных операций.
  2. Регенерация идентификатора сеанса при каждом изменении уровня безопасности (например, вход в систему). Вы можете даже восстановить идентификатор сессии каждый запрос, если хотите.
  3. Время ожидания сессий
  4. Не используйте регистр глобалов
  5. Храните данные аутентификации на сервере. То есть не отправляйте такие данные, как имя пользователя, в куки.
  6. Проверьте $_SERVER['HTTP_USER_AGENT']. Это добавляет небольшой барьер для захвата сессии. Вы также можете проверить IP-адрес. Но это создает проблемы для пользователей, которые меняют IP-адрес из-за балансировки нагрузки на несколько интернет-соединений и т. Д. (Что имеет место в нашей среде здесь).
  7. Заблокируйте доступ к сеансам в файловой системе или используйте пользовательскую обработку сеансов
  8. Для чувствительных операций рассмотрите требование, чтобы вошедшие в систему пользователи снова предоставили свои данные аутентификации.
88
6.06.2012 17:37:35
Использование SSL только для некоторых операций недостаточно, если у вас нет отдельных сеансов для зашифрованного и незашифрованного трафика. Если вы используете один сеанс через HTTPS и HTTP, злоумышленник украдет его по первому не HTTPS-запросу.
Kornel 16.11.2008 14:41:48
-1 пользовательский агент подделать тривиально. То, что вы описываете напрасно, это не система безопасности.
rook 23.04.2010 16:32:49
@ The Rook, это может быть тривиальный барьер (злоумышленник может захватить пользовательский агент жертвы, используя свой собственный сайт) и полагается на безопасность через неизвестность, но это все еще один дополнительный барьер. Если HTTP User-Agent должен был измениться во время использования сеанса, это было бы крайне подозрительно и, скорее всего, было бы атакой. Я никогда не говорил, что ты можешь использовать это один. Если вы объедините это с другими методами, у вас будет гораздо более безопасный сайт.
grom 27.04.2010 23:42:33
@ grom Я думаю, это все равно что положить кусок скотча на дверь и сказать, что это предотвратит проникновение людей.
rook 27.04.2010 23:59:33
Если вы проверяете пользовательский агент, вы блокируете все запросы от пользователей IE8, когда они переключают режим совместимости. Посмотрите на забаву, с которой я столкнулся при поиске этой проблемы, в моем собственном коде: serverfault.com/questions/200018/http-302-problem-on-ie7 . Я провожу проверку пользовательского агента, потому что подделывать, как говорили другие, такая банальная вещь.
bestattendance 9.11.2010 20:18:10

Одно из правил - вызывать session_regenerate_id каждый раз, когда изменяется уровень безопасности сеанса. Это помогает предотвратить перехват сеанса.

15
2.08.2008 02:43:42

Мои два (или более) цента:

  • Не доверять никому
  • Фильтр ввода, экранирование вывода (cookie, данные сеанса тоже ваши данные)
  • Избегайте XSS (держите ваш HTML правильно, посмотрите на PHPTAL или HTMLPurifier )
  • Глубокая защита
  • Не подвергайте данные

Крошечная, но хорошая книга на эту тему: Essential PHP Security от Chris Shiflett .

Essential PHP Security http://shiflett.org/images/essential-php-security-small.png

На главной странице книги вы найдете несколько интересных примеров кода и примеров глав.

Вы можете использовать метод, упомянутый выше (IP & UserAgent), описанный здесь: Как избежать кражи личных данных

11
6.04.2010 16:25:03
+1 за XSS-профилактику. Без этого невозможно защитить от CSRF, и, таким образом, кто-то может «покататься» на сеансе, даже не получив ID сеанса.
Kornel 27.10.2011 14:34:38

Я думаю, что одной из основных проблем (которая решается в PHP 6) является register_globals. Прямо сейчас один из стандартных методов, которые избегают, register_globalsсостоит в том $_REQUEST, чтобы использовать , $_GETили $_POSTмассивы.

«Правильный» способ сделать это (по состоянию на 5.2, хотя там немного глючит, но стабильно с 6, который скоро появится) - через фильтры .

Так что вместо:

$username = $_POST["username"];

вы бы сделали:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);

или даже просто:

$username = filter_input(INPUT_POST, 'username');
11
4.05.2012 09:41:40
Это не имеет никакого отношения к вопросу вообще.
The Pixel Developer 12.08.2009 04:02:00
В самом деле? Тогда почему в принятом ответе они не упоминают глобальные регистры? Не будет ли, с точки зрения большинства заурядных разработчиков, глобальные регистры и обработка переменных форм подпадают под эгиду «сессий», даже если технически это не является частью объекта «сессия»?
cmcculloh 18.08.2009 18:06:37
Я согласен, это не полностью отвечает на вопрос, но это определенно ЧАСТЬ ответа на вопрос. Опять же, это подчеркивает пункт в принятом ответе «Не используйте регистры глобалов». Это говорит о том, что делать вместо этого.
cmcculloh 18.08.2010 02:48:04

Этот документ по фиксации сессии имеет очень хорошие указатели, где может произойти атака. Смотрите также страницу фиксации сессии в Википедии .

9
5.03.2009 22:33:27

Использование IP-адреса - не самая лучшая идея в моем опыте. Например; В моем офисе есть два IP-адреса, которые используются в зависимости от нагрузки, и мы постоянно сталкиваемся с проблемами с использованием IP-адресов.

Вместо этого я решил сохранить сеансы в отдельной базе данных для доменов на моих серверах. Таким образом, никто в файловой системе не имеет доступа к этой информации о сеансе. Это было действительно полезно с phpBB до 3.0 (они с тех пор исправили это), но я думаю, что это все еще хорошая идея.

5
6.08.2008 20:44:55

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

Вот хороший учебник по setTimer () и clearTimer ().

3
2.08.2008 03:24:12

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

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

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

3
3.08.2008 13:14:48

Я настроил свои сессии так

на странице входа в систему:

$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);

(фраза определена на странице конфигурации)

затем в заголовке, который находится на остальной части сайта:

session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {       
    session_destroy();
    header('Location: http://website login page/');
    exit();     
}
3
19.07.2011 22:00:12

php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

eq Apache добавить заголовок:

X-XSS-Protection    1
3
13.10.2011 02:40:01
httpd.conf -> <FilesMatch "\. (php | phtml | aspx | htm | html) $"> Набор заголовков X-XSS-Protection "1" </ FilesMatch>
user956584 4.05.2012 13:52:43
Имейте в виду, что X-XSS-Protectionэто не совсем полезно. Фактически, сам алгоритм защиты может быть использован, что делает его еще хуже, чем раньше.
Pacerier 13.07.2012 10:31:53

Я бы проверил IP и User Agent, чтобы увидеть, если они меняются

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
    //Something fishy is going on here?
}
2
4.08.2008 21:38:05
IP-адрес может законно измениться, если пользователь находится за прокси-фермой с балансировкой нагрузки.
Kornel 16.11.2008 14:42:53
И user_agent может меняться каждый раз, когда пользователь обновляет свой браузер.
scotts 11.08.2009 19:03:03
@scotts Я согласен с IP-частью, но для обновления браузера вы устанавливаете сеанс при входе в систему, поэтому я не вижу, как они обновят браузер без создания нового сеанса после повторного входа.
JasonDavis 7.09.2009 11:36:01
Я считаю, что user_agent также может измениться при переключении между совместимым режимом в IE8. Это также очень легко подделать.
Heather Herbert 23.01.2011 11:25:50
Да, но как насчет пользователей, которые имели статический IP, например, GSM и меняются каждые полчаса. Итак, сохраненный IP в Session + host name, КОГДА IP! = REMOTE_ADDR проверяет хост и сравнивает hostanmes eq. 12.12.12.holand.nl-> When is holand.nl == true. Но у какого-то хоста было имя хоста на основе IP-адреса. Затем необходимо сравнить маску 88.99.XX.XX
user956584 4.05.2012 13:49:33

Если вы используете session_set_save_handler (), вы можете установить свой собственный обработчик сессии. Например, вы можете хранить ваши сессии в базе данных. Обратитесь к комментариям php.net за примерами обработчика сеанса базы данных.

Сеансы БД также хороши, если у вас несколько серверов, в противном случае, если вы используете файловые сеансы, вам необходимо убедиться, что каждый веб-сервер имеет доступ к одной и той же файловой системе для чтения / записи сеансов.

2
9.08.2008 03:28:43

Вы должны быть уверены, что данные сеанса в безопасности. Посмотрев на свой php.ini или используя phpinfo (), вы можете найти настройки сеанса. _session.save_path_ говорит вам, где они сохранены.

Проверьте разрешение папки и ее родителей. Он не должен быть общедоступным (/ tmp) или быть доступным для других веб-сайтов на вашем общем сервере.

Предполагая, что вы все еще хотите использовать сессию php, вы можете настроить php на использование другой папки, изменив _session.save_path_ или сохранить данные в базе данных, изменив _session.save_handler_.

Вы можете быть в состоянии установить _session.save_path_ в вашем php.ini (некоторые провайдеры позволяют это) или для апача + mod_php, в файле .htaccess в корневой папке сайта: php_value session.save_path "/home/example.com/html/session". Вы также можете установить его во время выполнения с помощью _session_save_path () _.

Посмотрите учебник Криса Шифлетта или Zend_Session_SaveHandler_DbTable для установки и альтернативного обработчика сеанса.

2
18.08.2008 17:12:34