Forum Moderators: phranque

Message Too Old, No Replies

Duplicate session id

Different users are getting the same session id

         

citpes

1:58 pm on Jun 4, 2009 (gmt 0)

10+ Year Member



Hi guys

I'm having a problem on a new server I am hosting with. It seems that users are being given session ids that are already in use by other users.

First of all, the server is running Debian Linux, with apache 1.3.34, fastcgi 2.4.2, mod_ssl 2.8.25 (and a couple more mods that don't seem important)

After a lot of research (never really thought about sessions before, they normally just work), I have come across a couple things that seem odd. By default, the session.gc_probability is set to 0 in Debian. This means the garbage collection never happens. Also, if the session.save_path is changed, garbage collection wont happen no matter what the probability.

So I got on the phone with my host and told them all this. After dropping their lip (they don't believe its a server issue), they have since changed the cookie_lifetime to 1440 (24min) and told me that should fix the problem.
If I look at the sessions stored on the server, none of them are older than 24min, so I assume the garbage collection is happening correctly.

But, it still seems to happen. I have added code which basically adds any new session id and IP into the database, and checks any new request against the records.
If it finds the session id is already in use for a different IP, it runs some code to stop the session, and give the user a new one (basically delete cookie, session_destroy etc, which I have tested by hijacking a session intentionally and it all seems to work as expected).

This is a hack around the problem though. Why is the server giving sessions that are already started? Sometimes the session was started only a minute or 2 before some other IP gets it again.

This problem is driving me crazy. It just shouldn't happen. Has anyone ever heard of something like this?

If there is any info I might have left off, let me know and I will post it up.

Thanks in advance!

citpes

7:30 am on Jun 8, 2009 (gmt 0)

10+ Year Member



Nothing? I guess I will have to just move the site to a different server.
I really wish I knew what was causing this issue, it's killing me

jdMorgan

1:13 pm on Jun 8, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Complex and relatively-rare problem, therefore a very limited number of members having any experience with it, so no replies yet...

All I can offer is generalities based on your described symptoms: Look into server-side caching issues and concurrency problems -- i.e. make sure that processes which must be single-threaded, such as assigning sessions, are in fact single-threaded.

Jim

citpes

1:38 pm on Jun 8, 2009 (gmt 0)

10+ Year Member



Hey Jim
Thanks for the reply. I figured it wouldn't get much activity based on the rarity of the problem. I pretty much laughed when the problem was reported, I thought it wasn't possible.

The site is simple php, so no threading there. But something I have just thought of, is that is does use nuSoap to call webservices. A quick google doesn't bring anything up, but could this contribute to the problem?

jdMorgan

2:35 pm on Jun 8, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No idea... Like many others, once we account for the factors of your server, its version, your OS and PHP versions, and all the other variables, I have no direct experience.

I wouldn't expect concurrency problems with a totally off-the-shelf solution. But is is very common for Webmasters and non-specialist script-writers to be unaware of the fact that care must be taken to enforce 'atomic' operations on all resources such as files and truly-global variables that are shared among multiple processes.

That is, processing of one HTTP request may be interrupted at any time, and processing on another HTTP request can begin. Unless steps are taken to lock shared resources so it can't happen, the second request can interfere with the first, or it may get invalid/incorrect data because of where the first process was interrupted.

For example, if your session number is calculated based on previously-stored numbers, and this process is interrupted after the current session number has been calculated by checking previously-reserved session numbers, but before this newly-calculated session number has itself been 'reserved' by saving it to disk, then the second request will re-calculate the same 'unreserved' number, and save it to disk. When the previously-interrupted request's process is resumed, it has already passed the point of calculating the 'next unreserved session number' and so it simply continues and writes that same 'last-used session number' to disk and exits. Now we have two requests using the same session number.

The solution is to lock the file where where session number reservations are stored, so that the read-last-reserved-number and write-newly-reserved-number process cannot be interrupted -- The second HTTP request's process must be forced to wait until after the first HTTP request's process has read the file, calculated the next session ID, and written that ID to the file. Only after that has been done can the second process be allowed to read the file.

Again, this is very general -- a subject covered in 'multi-task processing 101' general computer science classes. It is not specific to any of the factors in your described problems because again, I'm not familiar with any of your specifics. However, it is an extremely-common problem when people writing programs don't understand that modern computer operating systems execute multiple processes 'all at the same time' based on time slices and/or hardware and/or software events, and not strictly one-by-one.

A primary indicator of this type of problem is that the most likely sessions to 'collide' are the ones that are started almost simultaneously. If you never see a 'new' session get assigned the same ID as one that has been active for several seconds or more, then that is a strong indicator of this kind of concurrency problem. However, if you see a new session get assigned the same session ID as one started 30 seconds ago (or longer), then that indicates a completely-different kind of problem, such as a bug in the code or a server-side caching-control problem.

BTW, with languages or operating systems that do not provide explicit file-locking (e.g. a "flock" function), the simplest way to assure atomic operations is often to open the file for writing before it is to be read. It is very important that no 'exit' from the routine be possible after the file is thus locked and before it is subsequently unlocked. In fact, the best approach is almost always to calculate everything that needs to be calculated ahead of time, then lock the file, read it, make the last critical calculation based upon what was read, and then immediately write the result back to the file, unlock it, and proceed (or exit). The time that a shared resource remains locked can have a huge effect on performance, and must be minimized.

Jim

citpes

6:55 am on Jun 9, 2009 (gmt 0)

10+ Year Member



Wow, thanks for the detailed description.

I'm starting to think my method for detecting a duplicate session is flawed, and that the problem no longer happens.

When the complaint originally came through, the garbage collection settings were incorrect.
But before they were fixed, I added my own code to check for a duplicates. That code pretty much stored the session id and ip in the db. If I detect a session id already exists in the db, but the ip is different, I email myself with the error (and ended the session).

I added the code to a site on a different server that hasn't received any complaints, and I have had a couple emails notifying me of the error.
So perhaps my method is flawed? To be perfectly honest, the way sessions aregenerated is completely over my head. As I said in the original post, they normally just work, and php makes it really simple.

I suppose my only further action can be to stop ending sessions if I think they're a duplicate, and wait for any more complaints. It's not ideal, but I can't replicate it, so how do I know when its fixed or not?

Anyway, thanks for the help, it is appreciated