Безопасность сеанса PHP

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

SQL Injection: Атаки в реальной жизни и как это вредит бизнесу
SQL Injection: Атаки в реальной жизни и как это вредит бизнесу
Один-единственный вредоносный запрос может нанести ущерб вашему бизнесу. Уязвимости вашего кода могут привести к:
125
0
81 681
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

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

Я думаю, что одна из основных проблем (которая решается в 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');

Это вообще не имеет отношения к вопросу.

The Pixel Developer 12.08.2009 08:02

Действительно? Тогда почему в принятом ответе они упоминают не использовать глобальные регистры? Разве, с точки зрения большинства рядовых разработчиков, регистрация глобальных переменных и обработка переменных формы не подпадают под действие «сеансов», даже если они технически не являются частью объекта «сеанс»?

cmcculloh 18.08.2009 22:06

Я согласен, это не ответ от корки до корки на вопрос, но это определенно ЧАСТЬ ответа на вопрос. Опять же, это конкретизирует пункт в принятом ответе: «Не использовать глобальные переменные регистров». Это говорит о том, что делать вместо этого.

cmcculloh 18.08.2010 06:48

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

Вот хороший руководство для setTimer () и clearTimer ().

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

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

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

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

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
    //Something fishy is going on here?
}

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

Kornel 16.11.2008 17:42

А user_agent может меняться каждый раз, когда пользователь обновляет свой браузер.

scotts 11.08.2009 23:03

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

JasonDavis 07.09.2009 15:36

Я считаю, что user_agent также может измениться при переключении между совместимым режимом в IE8. Также очень легко подделать.

user70568 23.01.2011 14:25

Да, но как насчет пользователей, у которых был статический IP-адрес GSM, который меняется каждые полчаса. Итак, сохраненный IP в сеансе + имя хоста, WHEN IP! = REMOTE_ADDR проверяет хост и сравнивает хосты eq. 12.12.12.holand.nl-> когда holand.nl == true. Но у какого-то хоста было имя хоста на основе IP. Тогда нужно сравнить маску 88.99.XX.XX.

user956584 04.05.2012 17:49

@jasondavis Существует браузер Chrome.

Pacerier 13.07.2012 14:33

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

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

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

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

Ответ принят как подходящий

Чтобы обеспечить безопасность сеанса, нужно сделать несколько вещей:

  1. Используйте SSL при аутентификации пользователей или выполнении конфиденциальных операций.
  2. Повторно генерировать идентификатор сеанса при изменении уровня безопасности (например, при входе в систему). Вы даже можете восстанавливать идентификатор сеанса при каждом запросе, если хотите.
  3. Тайм-аут сессий
  4. Не используйте глобальные регистры
  5. Храните данные аутентификации на сервере. То есть не отправляйте такие данные, как имя пользователя, в cookie.
  6. Проверьте $_SERVER['HTTP_USER_AGENT']. Это добавляет небольшой барьер для перехвата сеанса. Вы также можете проверить IP-адрес. Но это вызывает проблемы у пользователей, которые меняют IP-адрес из-за балансировки нагрузки при нескольких подключениях к Интернету и т. д. (Что имеет место в нашей среде здесь).
  7. Заблокируйте доступ к сеансам в файловой системе или используйте настраиваемую обработку сеансов
  8. Для конфиденциальных операций рассмотрите возможность потребовать от пользователей, вошедших в систему, снова предоставить данные для аутентификации.

Использование SSL только для некоторых операций недостаточно, если у вас нет отдельных сеансов для зашифрованного и незашифрованного трафика. Если вы используете один сеанс через HTTPS и HTTP, злоумышленник украдет его при первом запросе, отличном от HTTPS.

Kornel 16.11.2008 17:41

Я согласен с porneL. Кроме того, для номера 6, если у злоумышленника есть ваш идентификатор сеанса, не будет ли он также иметь доступ к вашему пользовательскому агенту?

Chad 06.08.2009 02:16

Если вы регенерируете идентификатор сеанса, то идентификатор сеанса, который злоумышленник украл по запросу, отличному от HTTPS, бесполезен.

grom 23.03.2010 03:34

-1 пользовательский агент легко подделать. То, что вы описываете, является пустой тратой кода и не является системой безопасности.

rook 23.04.2010 20:32

Черт, я бы хотел дать вам еще -1 для использования ssl. Ни в коем случае cookie не может быть пропущен через http, это изложено в OWASP A3.

rook 23.04.2010 20:33

@ The Rook, да, User Agent можно подделать. Это всего лишь один маленький барьер. И что вы имеете в виду, говоря, что cookie не может просочиться через http. Да, его можно украсть. http - это простой текст.

grom 27.04.2010 07:27

@grom единственный барьер - это тот, который находится в вашем уме, вы не останавливаете атаку.

rook 27.04.2010 09:48

@The Rook, это может быть тривиальный барьер (злоумышленник может захватить пользовательский агент жертвы, используя свой собственный сайт) и полагается на безопасность через неясность, но это все еще один дополнительный барьер. Если пользовательский агент HTTP изменится во время использования сеанса, это будет крайне подозрительно и, скорее всего, станет атакой. Я никогда не говорил, что вы можете использовать его в одиночку. Если вы объедините его с другими методами, вы получите гораздо более безопасный сайт.

grom 28.04.2010 03:42

@grom Я думаю, это все равно что приклеить кусок скотча к двери и сказать, что это предотвратит проникновение людей.

rook 28.04.2010 03:59

Если вы проверяете пользовательский агент, вы блокируете все запросы от пользователей IE8, когда они переключают режим совместимости. Посмотрите, как весело я отследил эту проблему в моем собственном коде: serverfault.com/questions/200018/http-302-problem-on-ie7. Я беру проверку пользовательского агента, потому что это такая тривиальная вещь, чтобы подделать, как говорили другие.

bestattendance 09.11.2010 23:18

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

Kornel 27.10.2011 18:32

@grom Разве Chrome не меняет свой пользовательский агент автоматически, когда он обновляется в фоновом режиме, пока пользователь использует браузер? Таким образом вы блокируете реальных пользователей без уважительной причины. Не забывайте, что повышенное удобство использования - это еще и повышенная безопасность.

Pacerier 13.07.2012 14:26

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

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

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

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

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

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

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

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

По этой теме есть небольшая, но хорошая книжка: Основная безопасность PHP, Крис Шифлетт.

Основная безопасность PHP http://shiflett.org/images/essential-php-security-small.png

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

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

+1 за XSS-предотвращение. Без этого невозможно защититься от CSRF, и, таким образом, кто-то может «оседлать» сеанс, даже не получив его идентификатора.

Kornel 27.10.2011 18:34

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

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

$_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();     
}

php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

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

X-XSS-Protection    1

httpd.conf -> Комплект заголовка X-XSS-Protection "1"

user956584 04.05.2012 17:52

Имейте в виду, что X-XSS-Protection на самом деле бесполезен. Фактически, сам алгоритм защиты можно было использовать, что сделало его хуже, чем раньше.

Pacerier 13.07.2012 14:31

Другие вопросы по теме