php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38260 All web clients behind NAT firewall/router get the same $_SESSION id
Submitted: 2006-07-30 07:31 UTC Modified: 2006-07-30 18:04 UTC
From: anachronist+php at gmail dot com Assigned:
Status: Closed Package: Session related
PHP Version: 4.4.2 OS: RedHat Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: anachronist+php at gmail dot com
New email:
PHP Version: OS:

 

 [2006-07-30 07:31 UTC] anachronist+php at gmail dot com
Description:
------------
After several days of experimenting, I must conclude that this is a php bug concerning $_SESSION. I hope I'm wrong.

My local network has a single, static IP address with a NAT firewall/router, which connects several computers to my DSL service.  I'm sitting in front of these computers, testing my web site that's hosted remotely at my ISP's server.  My web site requires all users to log in.  I try to log in as different users on different machines.

The server uses the same session ID for ALL machines on my network.  The session id appears to be generated solely from the IP address (which is the IP address of my NAT), and not from any unique identifying data from my browser clients.

Reproduce code:
---------------
All of my php scripts, without exception, start out like this:

   session_save_path("/home/mydomain/public_html/lists");
   session_name('login_settings');
   session_start();

Then each php script checks what type of user is logged on the web site by calling this function:

   function isLoggedOn()
   {
      if (isset($_SESSION['superuser']))
         return 'superuser';
      if (isset($_SESSION['customer']))
         return 'customer';
      if (isset($_SESSION['user']))
         return 'user';
      return NULL; // unregistered or not logged in
   }

Upon receiving the return value from isLoggedOn(), the script behaves exactly the way it should depending on what type of user is logged in.  The value of $_SESSION['user'], $_SESSION['customer'], and $_SESSION['superuser'] is the user's ID in the MySQL table for that user type; the value is set by a login.php script.

I have three login.php scripts: for normal users, customers, and superuser.  Each login.php script queries the appropriate database for user ID and password, and sets some $_SESSION values, and ensures that any $_SESSION values for other user types are unset. Here, for example, is what happens with $_SESSION when a normal user logs in:

   $userid = $sql->GetValue('id');
   if ($userid) {
      $_SESSION['user'] = $userid;
      if (isset($_SESSION['customer']))
         unset($_SESSION['customer']);
      if (isset($_SESSION['superuser']))
         unset($_SESSION['superuser']);
      header("Location: http://www.example.com/userindex.php");
   } else header("Location: http://www.example.com/login.php?error=1")

Logging off deletes all $_SESSION data, deletes the session cookie, and finally calls session_destroy(). I have verified that the following excerpt from my logout.php works fine:

   $CookieInfo = session_get_cookie_params();
   $_SESSION = array(); // unset all session values
   setcookie(session_name(), '', time()-3600, $CookieInfo['path']);
   unset($_COOKIE[session_name()]);
   session_destroy();

If the problem I describe isn't a bug, what is going on?

Expected result:
----------------
Each web client accessing my site should correspond to a different session on the web server -- even if they're all behind a NAT router that has a single IP address.  That is, any modification of $_SESSION resulting from the actions of one client shouldn't affect other clients, because all should have unique sessions.

Actual result:
--------------
What actually happens:

Whenever another client on my local network logs in to the web site, the same session is used.  A new login event might change the value for $_SESSION['user'], or maybe add a new value $_SESSION['superuser'] -- resulting in all clients acting in accordance with the most recent login (or logout).  If one client on my network logs out, then ALL clients behave as if logged out when attempting further activity on the web site.

It doesn't seem to matter if the session cookie is deleted or not; what seems to matter instead is what the server stores as session data; when one user logs off, the session data is deleted and then all web browsers on my network act like they're logged off.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-07-30 10:10 UTC] tony2001@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions.  Due to the volume
of reports we can not explain in detail here why your report is not
a bug.  The support channels will be able to provide an explanation
for you.

Thank you for your interest in PHP.


 [2006-07-30 14:41 UTC] anachronist+php at gmail dot com
Sorry, that canned response isn't correct.

My report is NOT a support request.  I am reporting a bug, either in php itself, or in the documentation.  The simple fact is, $_SESSION is not working as expected or documented.

If there is anything further I need to describe, please let me know.  I thought I gave sufficient information for the problem to be reproduced.
 [2006-07-30 17:05 UTC] anachronist+php at gmail dot com
Update: I have isolated the problem to multiple users sharing the same sess_deleted file after logging off and then re-logging in, which gives the appearance of having one session shared across multiple users.  This is likely unrelated to being behind a single-IP-address NAT.

Observations:

A. After logging off, re-logging in doesn't re-set the session cookie.  It persists as having the value 'deleted', which is how it gets set after using set_cookie() with a timestamp of time()-3600 to force the cookie to expire.

B. The session file 'sess_deleted' - which appears from session_destroy() in the logoff script - is used as an actual session by browsers with a 'login_settings' cookie set to 'deleted'.  Any $_SESSION values subsequently introduced by the actions of one browser become part of the $_SESSION in all browsers.
 [2006-07-30 18:04 UTC] anachronist+php at gmail dot com
I am closing this bug report I created, and hope that others searching the bug reports for solving a similar problem will find this record.

The solution is to regenerate the session ID if the ID has the value 'deleted' -- like this:

   session_start();
   if (session_id() == 'deleted')
      session_regenerate_id(true);

The problem isn't due to multiple computers being behind a NAT having one IP address.  The problem is due to users sharing the 'sess_deleted' session file after logging off and then re-logging in without first closing their browser.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 26 06:01:32 2024 UTC