I am experiencing a what looks to me like a “race condition” when 2 users (almost) simultaneously access the same page. This causes the user to gain access to another users data.
I have the generic set up for users along with the module called Users & Rights. I am storing my session data in a database table.
I have been trying to catch this issue for some months and have finally managed to do so. I am using Yii Framework 1.1.20 and the user login process is as follows:
Sessions are stored in the database, I dont actually use $_SESSION to store user data (a field in the user table holds this information).
PHPSESSID is stored in a cookie.
From the login page, I store PHPSESSID from the cookie in a field of the form.
The user logs in, input is validated, Session Data is created and stored with the user record, including the PHPSESSID from the form (the real PHPSESSID). The user is then routed through 2 more controllers (Session/LoginCheck, Dashboard/home) to land on the Dashboard.
During a session, the user will frequently return to the dashboard.
When 2 or more users access the dashboard page (almost) simultaneously (via login or returning from a page within the site), both users will end up with the same cookie id and session data. I can confirm this by checking the browser based cookie with the cookie value stored in the $_COOKIE variable. A simple refresh of the dashboard on the page with the incorrect data results in the correct data being loaded.
I have researched race conditions with sessions in PHP and some of these offer the use of $_COOKIE to resolve race conditions with sessions so not really providing me with any solutions to my problem.
As I am able to trap the issue, I can easily resolve it with a refresh, but if there is a more stable solution available I would prefer to go down that route.
the current setup is a result of this issue beginning about 6 months ago. back then it was the copybook yii setup with user login and sessions (as per Larry Ullmans blog) and had been working successfully for several years. When I had a significant increase in users and activity this issue started occurring I had no way to reproduce it as I did not know how or why it was occurring. Over time I made many changes to the code (didnt touch the default user/session function so has always been generating a cookie and I have been using the UserModule->user function (running extension called Users and Rights)). The changes were merely to try to catch when this ocurred.
I have always been under the impression that the Yii process was rock solid, thats why I did not understand why it was happening. And even though most comments have been unhelpful they have been enough for me to work out what the issue might be.
the url when the issue occurred is the same for every user as I was relying on the session to provide details of the user. I wanted a “clean” url that the user would access the dashboard with, that url being “/dashboard/home”. It seems that having the same url for every user is what has triggered the problem.
I have since updated the code to provide a unique id with the URL and since doing so I can no longer reproduce the error. I will most likely revert back to the original config but leave my checking process in tact so I can catch the issue if it does occur again (that I am wrong in my assumption of what the problem was).
Anyway, suffice to say that I appear to have a resolution but will move forward with a guarded approach.
First of all, I recommend you start to explore the use of XDebug. For those not familiar it will be very tedious and for those familiar it still kind of tedious but what it offers is something you can never get from other means. Also, if you have not use any type of source control, you may want to do that sooner than later, too.
Now back to the issue itself, I feel the situation is either 1 of the following:
A user can load of their own information is just because they are the most recent person logged in. As you said the system did not have much user before, those users login, do their stuff and leave in just a short period of time. It’s all happen before the next user come in and do the same. If they, not only login, load other pages at similar time, one user might still load up another user’s information. This maybe because your related db query is not correctly conditioned.
There is a 1-hop delay in loading the correct user data. Since you said if the user refresh and the correct user information will be loaded. This lead me to think that at first the system has no idea what to load and so load with crippled conditions, e.g. 0, empty string, null etc. and lead to load up the other users’ information (of course you may argue why only the other user logged in around the same time. well, there maybe other situations which could lead to that).
The issue does not sound to me a race condition in any case but rather some confusion and some wrong assumption is made, about cookie, session as well as some timing issue (like which action happens before another etc).
Last but not least, make sure you have cache turned off while you are testing.