Как предотвратить совместное использование PHP-сессий между различными Apache vhosts?
Я настроил разные vhosts на Apache 2.2, и все работает отлично, пока я не понял, что сеансы PHP по умолчанию делятся.
Редактирование также является причиной того, что вы ВСЕГДА должны установить свой сеансовый_сопровождение или использовать обработку сеанса базы данных, если вы используете общий веб-хостинг. Кто-то может создать идентификатор сеанса и chmod его до 777 и использовать этот идентификатор сеанса на вашем сайте, чтобы обойти логины / или получить больше привилегий.
Это работает, потому что PHP не применяет, какие идентификаторы сеанса принадлежат какому-либо сайту. Я знаю это, потому что я проанализировал исходный код C / C ++ за сеансами в PHP, и потому что я задавался вопросом, как это возможно. Поэтому никогда не ставьте слишком много надежды на то, что массив $_SESSION
безопасен на совместном веб-хостинге, и вы не можете безопасно использовать это значение в SQL-запросе.
Некоторый код (файл session.c) в PHP из функции C php_session_start()
; да, эта функция вызывается, когда вы вызываете session_start()
из PHP (и единственная проверка, которую я видел, была в этих строках кода):
/* Check whether the current request was referred to by * an external site which invalidates the previously found id. */ if (PS(id) && PS(extern_referer_chk)[0] != '\0' && PG(http_globals)[TRACK_VARS_SERVER] && zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_REFERER", sizeof("HTTP_REFERER"), (void **) &data) == SUCCESS && Z_TYPE_PP(data) == IS_STRING && Z_STRLEN_PP(data) != 0 && strstr(Z_STRVAL_PP(data), PS(extern_referer_chk)) == NULL ) { efree(PS(id)); PS(id) = NULL; PS(send_cookie) = 1; if (PS(use_trans_sid) && !PS(use_only_cookies)) { PS(apply_trans_sid) = 1; } }
Единственная проверка – HTTP-заголовок «HTTP_REFERER», но мы все знаем, что это может быть фальшивка, так что это «безопасность через неизвестность». Единственный безопасный метод – использовать session_save_path
или использовать обработчик сеанса базы данных.
Чтобы установить session_save_path в php.ini, вы должны найти дополнительную информацию здесь http://php.net/manual/en/session.configuration.php .
Или, если PHP работает как модуль Apache, вы можете настроить его в файле htaccess контейнера vhost:
php_value session.save_path "path"
Или даже лучше PHPINIDir для каждого vhost:
<VirtualHost ip> [...] PHPINIDir /var/www/... [...] </VirtualHost>
ОБНОВЛЕНИЕ [Паника]:
Я просто добавляю полное решение этого ответа, так как это может помочь другим людям. Пример полной установки vhost:
<VirtualHost *:81> DocumentRoot /var/www/xxx1 <Directory "/var/www/xxx1"> AllowOverride All php_value session.save_path "/var/mysessionforproject_1" </Directory> </VirtualHost> <VirtualHost *:82> DocumentRoot /var/www/xxx2 <Directory "/var/www/xxx2"> AllowOverride All php_value session.save_path "/var/mysessionforproject_2" </Directory> </VirtualHost>
Что-то не так с вашим браузером, если оно отправляет файлы cookie через домены.
Разумеется, оба vhosts, использующие обработчик сеанса по умолчанию, будут записывать свои файлы сеанса в один и тот же каталог – просто переопределите его в конфигурации Apache vhost:
<VirtualHost a.example.com> ... php_value session.save_path "2;/var/www/a.example.com/data"