如何防止在不同的apache vhost之间共享PHP会话?

时间:2013-08-15 22:22:38

标签: php apache session vhosts

如何防止PHP会话在不同的Apache虚拟主机之间共享?

我在Apache 2.2上设置了不同的虚拟主机,一切运行正常,直到我意识到默认情况下共享PHP会话。

2 个答案:

答案 0 :(得分:7)

如果您使用共享虚拟主机,

编辑也是您始终应设置session_save_path(http://php.net/manual/en/function.session-save-path.php)或使用数据库会话处理(http://php.net/manual/en/class.sessionhandler.php)的原因。有人可以在那里创建会话ID并将其chmod到777并在您的站点上使用该会话ID来绕过登录/或获得更多权限。它也可以用于SQL注入。

这是有效的,因为PHP不会强制哪些会话ID属于哪个站点。我知道这是因为我已经在PHP中分析了会话背后的C / C ++源代码,因为我想知道这是如何实现的。因此,永远不要过于相信$_SESSION数组在共享Web主机上是安全的,并且您无法在SQL查询中安全地使用此值。

来自C函数php_session_start()的PHP中的一些代码(文件session.c);是的,当您从PHP调用session_start()时调用此函数(我看到的唯一检查是在这些代码行中):

/* 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或使用数据库会话处理程序。

要在php.ini中设置session_save_path,您应该在http://php.net/manual/en/session.configuration.php找到更多信息。

或者,如果PHP作为Apache模块运行,您可以在vhost容器的htaccess文件中配置它:

php_value session.save_path "path"

甚至更好的每个vhost的PHPINIDir:

<VirtualHost ip>
[...]
PHPINIDir /var/www/...
[...]
</VirtualHost>

更新[Panique]:

我只是在这个答案中添加完整的解决方案,因为这也可以帮助其他人。示例完整虚拟主机设置:

<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>

答案 1 :(得分:0)

如果您的浏览器跨域发送Cookie,则非常错误。

当然,使用默认会话处理程序的两个vhost都会将其会话文件写入同一目录 - 只需在Apache vhost配置中覆盖它:

<VirtualHost a.example.com>
    ...
    php_value session.save_path "2;/var/www/a.example.com/data"