Description
Symfony version(s) affected
6.0
Description
On Debian systems, to prevent session hijacking, the default session.save_path
is not listable by PHP. This is a sound security feature. In order for this to work :
- session gc must be blocked in the HTTP context (SAPI = CGI or FPM)
- session gc must be handled by an external, privileged process (a root cronjob on Debian)
Thus Debian ships with session.gc_probability=0
and the proper external gc in /etc/cron.d/php
. It's been working like a charm for 10+ years (I've traced the presence of this setup since at least Debian 6 / 2011), it still ships that way.
Symfony forces session.gc_probability=1
which seems to start from a complaint from a filled cache folder (see #10349). It ended with this very strange situation where :
- the default situation with a native file-based session handler on Debian is broken, in a nasty and heisenbuggy way (triggers on 1 out of 1000 queries on average)
- the documentation suggests how to unbreak it (https://symfony.com/doc/current/components/http_foundation/session_configuration.html#configuring-garbage-collection)
Debian-based users thus have a very hard time rediscovering the obscure problem and fixing it.
IMO if Symfony is configured to use the native PHP handler, it should honor the native settings : in this case it is the php.ini's owner responsability to properly configure it, and it turns out Debian ships a well configured situation. A value of session.gc_probability=1
can't be forced by ignoring the whereabouts of the session handler, because a value of 0 can be sound and right.
I think the intention was right (never ship a configuration which let a session storage endlessly fills up), but the fix is wrong.
I would like to request to at least not break Debian native file-based session handler by default.
How to reproduce
Grab a Debian OS (>= 6), install your preferred runtime (php-cgi | php-fpm | libapache2-mod-php), and have a simple script like :
<?php
ini_set('session.gc_probability', 1);
session_start();
$_SESSION['foo']='bar';
Then make a few thousand requests on this script :
ab -c1 -n5000 localhost/testsess.php
And find in your error.log a rare occurence of :
PHP Notice: session_start(): ps_files_cleanup_dir: opendir(/var/lib/php/sessions) failed: Permission denied (13) in /var/www/default/testsess.php on line 3
Possible Solution
Only force session.gc_probability=1
when using a non-native session handler, where Symfony and its configuration are really in charge of the sessions.
Additional Context
No response