如何防止在不同的 apache 虚拟主机之间共享 PHP 会话? [英] How to prevent PHP sessions being shared between different apache vhosts?

查看:39
本文介绍了如何防止在不同的 apache 虚拟主机之间共享 PHP 会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How to prevent PHP sessions from being shared between different Apache vhosts?

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

I've set up different vhosts on an Apache 2.2 and everything works perfectly, until I realized that the PHP sessions are shared by default.

推荐答案

编辑也是你总是应该设置 session_save_path ( http://php.net/manual/en/function.session-save-path.php )或使用数据库会话处理( http://php.net/manual/en/class.sessionhandler.php ) 如果你在共享虚拟主机上.有人可以在该站点上创建会话 ID 并将其修改为 777,然后在您的站点上使用该会话 ID 来绕过登录/或获得更多权限.它还可以用于 SQL 注入.

Edit is also the reason why you ALWAYS should set your session_save_path ( http://php.net/manual/en/function.session-save-path.php ) or use database session handling ( http://php.net/manual/en/class.sessionhandler.php ) if you are on an shared webhosting. Somebody can create an session id on there site and chmod it to 777 and use that session id on your site to bypass logins/or get more privileges. It can also be used for SQL injections.

这是有效的,因为 PHP 不强制执行哪些会话 ID 属于哪个站点.我知道这一点是因为我已经分析了 PHP 会话背后的 C/C++ 源代码,并且因为我想知道这怎么可能.所以永远不要太相信 $_SESSION 数组在共享虚拟主机上是安全的,并且你不能在 SQL 查询中安全地使用这个值.

This works because PHP doesn't enforce what session IDs belongs to what site. I know this because I've analysed the C/C++ source code behind sessions in PHP, and because I wondered how this could be possible. So never put too much trust that the $_SESSION array is safe on shared web hosting and you can't safely use this value in a SQL query.

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

Some code (file session.c) in PHP from C function php_session_start(); yes, this function is called when you call session_start() from PHP (and the only check I saw was in these lines of code):

/* 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 HeaderHTTP_REFERER",但我们都知道它可以被伪造,所以这是通过默默无闻的安全性".唯一安全的方法是使用 session_save_path 或使用数据库会话处理程序.

The only check is the HTTP Header "HTTP_REFERER", but we all know it can be faked, so this is "security through obscurity". The only safe method is to use session_save_path or use a database session handler.

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

To set session_save_path in the php.ini, you should find more information here http://php.net/manual/en/session.configuration.php.

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

Or, if PHP is running as an Apache module, you can configure it in the htaccess file of vhost container:

php_value session.save_path "path"

或者更好的是每个虚拟主机的 PHPINIDir:

Or even better a PHPINIDir per vhost:

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

更新 [Panique]:

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

I'm just adding the full solution to this answer, as this might help other people too. A sample full vhost setup:

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

这篇关于如何防止在不同的 apache 虚拟主机之间共享 PHP 会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆