php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #9669 Session write-out race condition
Submitted: 2001-03-10 04:55 UTC Modified: 2001-04-28 23:21 UTC
From: dave2 at wetstring dot net Assigned:
Status: Closed Package: Session related
PHP Version: 4.0.3pl1 OS: Debian GNU/Linux 2.2
Private report: No CVE-ID: None
 [2001-03-10 04:55 UTC] dave2 at wetstring dot net
Initally from time to time, very rarely, we'd login to the site (which does logins as a form submission), and we'd get back to the page we're supposed to be at but without seeming to be logged in. 

The page that the login form submits to does very little, it just checks the details provided by the form in a database, and sets a session variable with the user's real ID, which all pages consider to be "logged in". Then, they're redirected back to the refering page. 

Works fine, 99.9% of the time, but under situations where access is good (eg, 50ms away from the webserver over cable + ethernet) sometimes it just wouldn't work. It got a _lot_ worse when we started pushing session data into a database.

Initally we thought it was our custom session save stuff, but removing it we could still reproduce the problem (it was just harder to reproduce). Finally, we added a whole lot of debugging calls to error_log() and found what was going on.

There's a race condition between the end of a page and when the session handler actually writes out the session data, vs when a new page is requested. If the remote browser requests a page before PHP has written out the session stuff, it'll get the old session infomation. From our debugging:

[Sat Mar 10 21:58:49 2001] [error] uri:
/login.php?user=samteste&password=x&uri=%2F sql: select
verifyLogin('samteste','x')
[Sat Mar 10 21:58:49 2001] [error] uri: / sql: SELECT value FROM sessiondata WHERE sesskey =
'35760d1b61748cc467b3c685916c3980' AND expiry > now()
[Sat Mar 10 21:58:49 2001] [error] uri:
/login.php?user=samteste&password=x&uri=%2F sql:
        UPDATE sessiondata
        SET    expiry = now()+'1440s',
               value = 'playerid|s:4:\"1542\";attempt|i:1;'
        WHERE  sesskey = '35760d1b61748cc467b3c685916c3980'

Roughly, we see this sequence as:
 - The page that verifies the login is called (/login.php), and the login is verified, which updates the session variable. Before exit, this page issues a redirect to /.
 - The browser then processes the redirect, and requests the new URL (/), retriving the "current" session data
 - The session data from login.php is only just now written out.

We have a workaround in PHP (we have a function called redirect() which first calls our session_write handler with the session_id() and session_encode(), before outputing the headers..) but we'd prefer the session handling worked as advertised, so to speak :)

Note: we've verified with a packet sniffer that the browser is closing the connection before opening a new one for the new URL. It's not the browser jumping the gun. 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-03-16 17:24 UTC] sas@php.net
In the context of the default files handler, this happens:

The handler acquires an exclusive lock when opening the session. We never release that lock, we simply close the file descriptor in the close handle. And that takes place after we write out the session data.

Hence, your described scenario cannot take place, as all requests to a single session are always serialized.

It can take place, if you don't plant proper locking into your session handler though.
 [2001-04-28 23:21 UTC] sniper@php.net
If I understood Sascha's reply correctly, this is not
any bug in PHP. Reopen if this is not the case.

--Jani

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 18:02:40 2024 UTC