Cleanup PHP Session Files

cleanup php session files

To handle session properly, take a look at http://php.net/manual/en/session.configuration.php.

There you'll find these variables:

  • session.gc_probability
  • session.gc_divisor
  • session.gc_maxlifetime

These control the garbage collector (GC) probability of running with each page request.

You could set those with ini_set() at the beginning of your script or .htaccess file so you get certainty to some extent they will get deleted sometime.

How can old sessions in /var/lib/php/session/ be flushed?

Yes, discussion of this can be found in the manual here:

You want to look at all the session.gc_ settings, as those are the variables that effect how likely it is that garbage collection is running.

With that said, something is clearly wrong, as it seems like your session files are not being deleted.

You do need to factor in the session.gc_maxlifetime setting in your php.ini file, as no file will be deleted until that number of seconds since file creation has passed. If your gc_maxlifetime is too long, files will accumulate.

This script is a recommended cron - oriented command line php script that can be installed and run daily or weekly to run the garbage collector. I would start with that and see what happens.

There could be permissions issues that are actually preventing the garbage collector from deleting the sessions, so starting with a manual run of this program and seeing what happens to the number of session files would be a good start. If you have php7.1 this is the recommended code from the manual.

<?php
// Note: This script should be executed by the same user of web server process.

// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

A program for older versions of php that should work in a similar fashion would be:

<?php
ini_set('session.gc_probability', '1');
ini_set('session.gc_divisor', '1');
session_start();
session_destroy();
?>

The idea here is that you are guaranteeing that the garbage collector will run by making the probability 100% for this script.

Delete Session files automatically in PHP

Probably this example will help you

 <?php 
// you have to open the session to be able to modify or remove it
session_start();

// to change a variable, just overwrite it
$_SESSION['variable_name']='variable_value';

//you can remove a single variable in the session
unset($_SESSION['variable_name']);

// or this would remove all the variables in the session, but not the session itself
session_unset();

// this would destroy the session variables
session_destroy();
?>

Session Files Not Getting Cleaned Up

Yes, you need to manually clean them up because you've setup your own session save path. You can check the age of a file and delete if it's older than x days/minutes whatever:

cd /path/to/sessions; find -cmin +24 | xargs rm

Taken from the note part of php.ini:

; NOTE: If you are using the subdirectory option for storing session files
; (see session.save_path above), then garbage collection does *not*
; happen automatically. You will need to do your own garbage
; collection through a shell script, cron entry, or some other method.
; For example, the following script would is the equivalent of
; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
; cd /path/to/sessions; find -cmin +24 | xargs rm

See as well this related/duplicate question: cleanup php session files


"Single" command:

find /path/to/session -name sess_* -cmin +24 -exec rm {} \;

Deleting old session files from custom set session folder?

As long as you don't use the N; option on php's session.save_path setting, PHP will auto-clean stale sessions according to the session.gc_probability / session.gc_divisor / session.max_lifetime settings

If you've rolled your own session handlers, you'll be responsible for the cleanup.

Can I safely delete all content in /var/lib/php5?

Let PHP's gc perform cleanup by itself. Find php.ini and change session.gc_probability to something bigger, save it and restart Apache (call any php script). It says here http://somethingemporium.com/2007/06/obscure-error-with-php5-on-debian-ubuntu-session-phpini-garbage

In Debian and Ubuntu, /var/lib/php5, where the session data is stored,
has permissions of drwx-wx-wt and should only be cleaned by a cron
script. So, the package maintainers disable automatic session garbage
collection.

Or you could try to put ini_set('session.gc_probability', 100); session_start(); (if your session.gc_divisor is equal to 100) in one of your scripts and call it. The best way is to put in empty php file, because it might perform cleanup for a very long period of time.

ps: I would also try to leave session.gc_probability 1 and set session.gc_divisor to 1. It should call gc at every run, but you need it just for a directory cleanup.

And check your cron /etc/cron.d/php5 - it should run every half an hour to purge session files in the /var/lib/php5/ directory.

pps: found interesting comment

This does not disable it (it is commented out). The default within the
engine is still used - phpinfo() shows the value to be 1. There is a
problem with garbage collection in Debian (and thus Ubuntu) but that's
due to PHP wanting to vacuum garbage that has already been removed by
the cron script. This causes an error that may be displayed on the
unlucky page.

How to handle PHP sessions efficiently?

1) Even when the test lifetime value (60 seconds) is over, the session file remains in the custom directory. I read this is because I set a custom directory. Is this true?

No, the custom directory is picked up by the session GC and the files will be cleaned up. It just doesn't happen immediately.

2) What would be an efficient way to delete all non-used/expired session files? Should I add $_SESSION['last_activity'] with a timestamp and let a cronjob look in my custom dir, get the session file data and calculate expired sessions to delete it?

PHP 7.1 has session_gc(), which you can call from a cronjob and it will do everything necessary.

On older PHP versions, you'd rely on the probability-based GC by default, where cleanups are performed randomly.

This may not be particularly efficient, but it has been the only universal solutions for over a decade, so ...

However, if your server runs Debian, it likely has session.gc_probability set to 0 and using a Debian-specific crontab script to do the cleanup at regular intervals - you will have problems with a custom directory in that case, and there are a few options:

  • Manually re-enable session.gc_probability.
  • Configure session.save_path directly in your php.ini, so the default cron script can pick it up.
  • Don't use a custom dir. Given that you currently have getcwd().'/a/', I'd say the default sessions dir on Debian is almost certainly a more secure location, so it would objectively be a better one.
  • Write your own cronjob to do that, but you have to really know what you're doing. $_SESSION['last_activity'] is not even usable for this; file access/modified times provided by the file-system itself are.

3) Should I avoid saving those unneeded sessions by those bot crawlers just looking for the string "bot" inside $_SERVER['HTTP_HOST'] or is there a better way to identify "non-human visitors"/crawlers?

You're thinking of $_SERVER['HTTP_USER_AGENT'], but no - this isn't a solution.

Little known (or largely ignored, for convenience), but the only way to do this correctly is to never start a session before login.

The annoyance of crawlers triggering useless session files is a neglible issue; the real concern is a determined attacker's ability to fill up your session storage, use-up all possible session IDs, avoid session.use_strict_mode - none of these attacks are easy to pull off, but can result in DoS or session fixation, so they shouldn't be easily dismissed as possibilities either.

P.S. Bonus tip: Don't use $_SERVER['HTTP_HOST'] - that's user input, from the HTTP Host header; it might be safe in this case due to how cookies work, but it should be avoided in general.

Cleanup after PHP Session

Since this is not a true login mechanism there won't be a logout or session timeout and I don't want to impose a timeout.

Actually - it is a true login mechanism - you have a user perform a login by "entering name on form" - then they are logged in. It is just different to a username.

You just dont have a "logout" mechanism.

You can not rely on a browser to tell you when it is closed, leaving etc - it is unreliable and will not work. Therefore - your best (and only real) solution is to check server side for the state of the session. Just create a CRON job that runs a php file every 15mins or so. Each time the php file is run - it checks all sessions for their last activity time. If the last activity time is longer than the timeout limit, then run your cleanup.

I know you said you dont want to "impose a timeout" - but you'll going to have to draw a line in the sand somewhere, and say "hey, if my users are inactive for X mins (or even X hours) - then it is safe to assume they have left and are not coming back!". Just set a really high threshold.

delete session files after a time from creation

thanks but I think I could solve it by myself

the solution was simple

  if ($handle = opendir('sessions')) {

foreach (glob("sessions/sess_*") as $filename) {
if (filemtime($filename) + 400 < time()) {
@unlink($filename);
}
}

}


Related Topics



Leave a reply



Submit