Які рекомендації щодо забезпечення безпеки відповідальної сесії за допомогою PHP? Інформація є в усьому Інтернеті, і саме час приземлитися в одному місці!
Які рекомендації щодо забезпечення безпеки відповідальної сесії за допомогою PHP? Інформація є в усьому Інтернеті, і саме час приземлитися в одному місці!
Відповіді:
Щоб захистити сеанс, потрібно виконати декілька дій:
$_SERVER['HTTP_USER_AGENT']
. Це додає невеликий бар'єр для викрадення сеансів. Ви також можете перевірити IP-адресу. Але це спричиняє проблеми для користувачів, які змінюють IP-адресу через балансування навантаження в декількох підключеннях до Інтернету тощо (що в нашому середовищі тут).Одне правило - викликати session_regenerate_id кожного разу, коли рівень безпеки сеансу змінюється. Це допомагає запобігти викрадення сеансу.
Мої два (або більше) копійок:
На цю тему є крихітна, але хороша книга: Основна безпека PHP Кріса Шифлетта .
Основна безпека PHP http://shiflett.org/images/essential-php-security-small.png
На домашній сторінці книги ви знайдете кілька цікавих прикладів коду та зразки розділів.
Ви можете використовувати техніку, згадану вище (IP та UserAgent), описану тут: Як уникнути крадіжки особистих даних
Я думаю, що однією з головних проблем (яка вирішується в 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');
Цей документ про фіксацію сеансу має дуже хороші вказівки, де може наступити атака. Дивіться також сторінку фіксації сеансу у Вікіпедії .
Використання IP-адреси насправді не найкраща ідея. Наприклад; мій офіс має дві IP-адреси, які звикають залежно від завантаження, і ми постійно стикаємося з проблемами, використовуючи IP-адреси.
Натомість я вирішив зберігати сеанси в окремій базі даних для доменів на своїх серверах. Таким чином, ніхто з файлової системи не має доступу до цієї інформації про сеанс. Це було дуже корисно для phpBB до 3.0 (вони з тих пір виправили це), але я все одно гарна ідея.
Це досить банально і очевидно, але не забудьте сеанс_destroy після кожного використання. Це може бути важко реалізувати, якщо користувач не виходить з явного виходу, тому для цього може бути встановлений таймер.
Ось хороший підручник із setTimer () та clearTimer ().
Основна проблема з PHP-сесіями та безпекою (окрім викрадення сеансу) пов'язана з тим, в якому середовищі ви знаходитесь. За замовчуванням PHP зберігає дані сеансу у файлі у тимчасовій директорії ОС. Без особливих роздумів або планування це каталог, який читається у всьому світі, тому вся інформація про сеанси є загальнодоступною для всіх, хто має доступ до сервера.
Що стосується підтримки сеансів на декількох серверах. У цей момент було б краще переключити PHP на сеанси, якими керує користувач, коли він викликає надані функції CRUD (створювати, читати, оновлювати, видаляти) дані сеансу. У цей момент ви можете зберігати інформацію про сеанс у базі даних або подібному до мешканця рішення, щоб усі сервери додатків мали доступ до даних.
Зберігання власних сеансів також може бути вигідним, якщо ви перебуваєте на спільному сервері, оскільки це дозволить вам зберігати його в базі даних, яка часто маєте більше контролю над файловою системою.
Я налаштовував свої сеанси так:
на сторінці входу:
$_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();
}
session.cookie_httponly = 1
change session name from default PHPSESSID
X-XSS-Protection 1
X-XSS-Protection
це зовсім не корисно. Насправді сам алгоритм захисту можна було експлуатувати, роблячи його гірше, ніж раніше.
Я перевірив би і IP-адресу, і Агент користувача, щоб побачити, чи не змінюються вони
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
|| $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
//Something fishy is going on here?
}
Якщо ви використовуєте session_set_save_handler (), ви можете встановити власний обробник сеансу. Наприклад, ви можете зберігати свої сеанси в базі даних. Зверніться до коментарів php.net для прикладів обробника сесії бази даних.
Сесії БД також хороші, якщо у вас є кілька серверів, інакше, якщо ви використовуєте файлові сеанси, вам слід переконатися, що кожен веб-сервер мав доступ до однієї файлової системи для читання / запису сеансів.
Ви повинні бути впевнені, що дані сеансу є безпечними. Переглядаючи ваш 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 для встановлення та альтернативного обробника сесії.