Re: [VOTE] RFC: Introduce session_start() options - read_only, unsafe_lock, lazy_write and lazy_destroy

From: Date: Fri, 14 Feb 2014 07:47:46 +0000
Subject: Re: [VOTE] RFC: Introduce session_start() options - read_only, unsafe_lock, lazy_write and lazy_destroy
References: 1  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Hi Stas,

On Thu, Feb 13, 2014 at 12:39 PM, Yasuo Ohgaki <[email protected]> wrote:

> I almost forgot to start vote for this RFC.
> This RFC is to introduce options to session_start().
> Options are read_only, lazy_write, unsafe_lock and lazy_destroy.
> lazy_destroy is bug fix in fact.
>

I think there is some misunderstanding. lazy_destroy is design bug fix
indeed. Without it, we cannot make sure that old sessions are deleted when
session_regenerate_id() is called, or unwanted race condition if it is
deleted. Leaving old session alive works, but it opens attack vector
unnecessarily.

I thought "deleted session data should be deleted" like you at first. You
can see that in this thread.

http://marc.info/?l=php-internals&m=138242492914526&w=2

However, conclusion is "Session data cannot be deleted immediately".
Accesses from a client are not serialized. Therefore, immediate session
data deletion results in unwanted behavior. Application that manages
personal photos is good example.

 - User can only display photos when he/she is logged in.
 - There are private photos in user's personal page. i.e. All photos are
protected by authenticated session.

When browser accesses to the personal page, application checks
authentication status and returns HTML page for it if user's session is
authenticated. Browser tries to load images which require authenticated
session. If session_regenerate_id() is called (timeout, etc) while loading
images, what happens? If old session data is deleted, other images cannot
be loaded because requests are done by old session ID. This scenario valid
since current browser uses multiple connections to load resources of a web
page.

Currently, session_regenerate_id() does not delete session by default. It
leaves old one. It is made not to delete old session data by default so
that it will work under such scenario.

What happens to  "should be deleted" old session data? It keeps working as
valid session until it is deleted by GC. This behavior is not acceptable.
If user's session is stolen by JavaScript injection/sniffering/etc,
attacker may abuse stolen session forever. All attacker has to do is access
web server so that GC will not delete it. session_regenerate_id() does not
help because attacker has valid authenticated session already.

The solution for this is delayed deletion when session should be deleted.
lazy_destroy (name could be changed) allows to access deleted session data
specified amount of time. No more than that. (90 sec by default).
Therefore, attackers cannot abuse stolen sessions forever and
session_regenerate_id() works as it should. i.e. Create new session and
delete old one to mitigate risk of stolen session.

By the way, session_destroy() could be made to delete session data
immediately. It is made not to delete immediately to keep consistent
destroy behavior with session_regenerate_id(). Unless user use
session_destroy() strange way, immediate deletion should not be a problem.

I hope I explained well enough to understand what is the
session_regenerate_id() bug.

Regards,

--
Yasuo Ohgaki
[email protected]


Thread (13 messages)

« previous php.internals (#72583) next »