SessionHandler relies on GC cleanup but it should additionally check timestamps

Created on 1 May 2025, 12 days ago

Problem/Motivation

The only way Drupal expire a session is via GC, which is based on probability by default.

Because of this, it is possible to gain access to a session that should have expired but hasn't been deleted by the GC.

Even if the GC is run periodically (eg via cron), there is still a possibility to gain access in between cron runs.

The problem lies in \Drupal\Core\Session\SessionHandler::read not checking the timestamp compared to the session lifetime.

Looking at Symfony and Laravel, both are checking the expiration/lifetime when reading a session.

References:

Steps to reproduce

  • Set the gc_probability to 0 in session.storage.options in services.yml parameters, to make sure the GC don't run on request.
  • Lower the gc_maxlifetime, for example 300 (5 minutes)
  • Rebuild the container
  • Login to the site
  • Idle for >5 minutes
  • Reload or visit the site again
  • User is not logged out, session is still active even if its lifetime has exceeded the gc_maxlifetime

Proposed resolution

  • Compare timestamp with session.gc_maxlifetime in \Drupal\Core\Session\SessionHandler::read (eg adding condition in the query)
  • (Not necessary) Introduce a new concept of session TTL that decouples from PHP session.gc_maxlifetime config, but fall back to it.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Active

Version

11.1 🔥

Component

base system

Created by

🇮🇩Indonesia el7cosmos 🇮🇩 GMT+7

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024