Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent PHP sessions being shared between different apache vhosts?

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

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.

like image 967
Sliq Avatar asked Aug 15 '13 22:08

Sliq


People also ask

What is Session_start PHP?

session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie. When session_start() is called or when a session auto starts, PHP will call the open and read session save handlers.

What does PHP use to track sessions between the client and server?

Sessions use cookies to identify remote clients. That means that Sessions won't work if the client's web browser doesn't accept cookies. PHP keeps Sessions' data inside files.

What is the alternative of Session in PHP?

The alternative to sessions is cookies (in fact, sessions are usually implemented using cookies). But cookies should only be used if you want to store small amounts of data.


1 Answers

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.

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.

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

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.

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

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"

Or even better a PHPINIDir per vhost:

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

UPDATE [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>
like image 114
Raymond Nijland Avatar answered Sep 25 '22 18:09

Raymond Nijland