Welcome Guest, Not a member yet? Register   Sign In
Bug in native session library (sess_update)?
#1

[eluser]sheldonnbbaker[/eluser]
This is likely gonna be a long post, so please bear with me. Smile

I'm using the native session class with CI 1.7.2 with database-storage enabled. Throughout most of my development of my app, I've been randomly logged out of the current user at random times and couldn't figure out why. After a bunch of tracing and debugging in the session class, this is what I've come up with.

This error is most easily reproduced with a sess_update config variable set really low (even 2 seconds does the trick).

The gist of the bug is that if an HTTP request is sent to the server almost right after the previous one (within one second), the library gets confused and ends up destroying the current session (sess_destroy()) and then creates a new one.

Here's what's going on (this is after a successful login and setting $this->session->userdata['logged_in_user_id'] = 100700):


2010-03-11 10:26:11 --> Session Class Initialized [on URI /user/100700/]
2010-03-11 10:26:11 --> sess_read() : Fetching $_COOKIE directly: ...[serialized array of session data]...session_id = efabf9c72cfa8e7ac83de48f62f10efd
2010-03-11 10:26:12 --> sess_read() : Looking for session in DB. Searching for session id: efabf9c72cfa8e7ac83de48f62f10efd
2010-03-11 10:26:12 --> sess_update() : Updating session.
2010-03-11 10:26:12 --> sess_update() : Updating session. Old session id: efabf9c72cfa8e7ac83de48f62f10efd
2010-03-11 10:26:12 --> sess_update() : Updating session. New session id: 74758bc9a62a132d9f9a175ccb62a266
2010-03-11 10:26:12 --> _set_cookie() : About to setcookie() with this $cookie_data: ...[serialized array of session data]...session_id = 74758bc9a62a132d9f9a175ccb62a266
2010-03-11 10:26:12 --> _set_cookie() : setcookie() completed. Checking $CI->input->cookie(): ...[serialized array of session data]...session_id = efabf9c72cfa8e7ac83de48f62f10efd
2010-03-11 10:26:12 --> Session routines successfully run

2010-03-11 10:26:13 --> Session Class Initialized on /user/100700/
2010-03-11 10:26:13 --> sess_read() : Fetching $this->input->cookie(): ...[serialized array of session data]...session_id = efabf9c72cfa8e7ac83de48f62f10efd

As you can see, even after a NEW request, $CI-input->cookie() returns the session with the OLD session id. The database, however, has been updated with the NEW session id. And so, the next request will get the old session id from the cookie, and look for a corresponding session id in the database (which doesn't exist, since it's session id WAS updated). As a result, the session is destroyed.

I don't quite understand the bug fully, but is it maybe possible there is a lag time between setcookie() and reading the $_COOKIE array on the next request? How long does it take to overwrite that cookie with the new session id?

Any light that can be shed on the situation would be most appreciated. Smile
#2

[eluser]sheldonnbbaker[/eluser]
I think I've figured out exactly why this is happening.

On sess_update(), both the cookie and the database are updated. New data from the database can be read from immediately after it is updated (duh). But, the $_COOKIE array remains the same throughout the entire request. So, if two requests are made almost immediately after each other (by the same user), the first request will call sess_update() (if the session id has expired), so the cookie and database will be updated. However, the second request is still reading old session id from the $_COOKIE array while the database carries the new session id.

So, not sure what to do from here - as I can't have users being logged out. I could set sess_time_to_update to a huge number, but that just disables what's otherwise a good security feature. And this problem will still arise whenever sess_update() is called.

My app constantly has requests right after one another (AJAX calls as well as CSS and JS which are output through CI), so it's not an option to just limit the number of requests.
#3

[eluser]n0xie[/eluser]
The bug was discussed here

I was made aware of the bug here. I tried to make a quick fix but failed horrible. As of yet I haven't thought of a solution to fix this, nor has Ellislabs closed the bug so I guess we have a problem for now. Maybe they fixed it in CodeIgniter 2.0.
#4

[eluser]sheldonnbbaker[/eluser]
[quote author="n0xie" date="1268368151"]The bug was discussed here

I was made aware of the bug here. I tried to make a quick fix but failed horrible. As of yet I haven't thought of a solution to fix this, nor has Ellislabs closed the bug so I guess we have a problem for now. Maybe they fixed it in CodeIgniter 2.0.[/quote]

Sad

Thanks
#5

[eluser]ciKD[/eluser]
I am just starting with CI, with 1.7.2 and read a lot about sessions etc. so I came here as well.

Question: Is it not advisable to use native session lib for now with 1.7.2?

Edit: Probably I should use http://codeigniter.com/wiki/Session_Hybrid/ ?
#6

[eluser]sheldonnbbaker[/eluser]
[quote author="ciKD" date="1270243972"]I am just starting with CI, with 1.7.2 and read a lot about sessions etc. so I came here as well.

Question: Is it not advisable to use native session lib for now with 1.7.2?

Edit: Probably I should use http://codeigniter.com/wiki/Session_Hybrid/ ?[/quote]

The session library works fine - other people have made improvements or outright replacements for it (see the wiki for ones like DB_Session) which I myself prefer using.

The native library was a problem for me when I made an app that made a ton of AJAX requests and routed assets (CSS and JS) through CodeIgniter - as there were a lot of parallel requests.
#7

[eluser]ciKD[/eluser]
[quote author="sheldonnbbaker" date="1270258333"]
The session library works fine ...
[/quote]
It above the out-of-the-box library which comes with 1.7.2 ?
[quote author="sheldonnbbaker" date="1270258333"]
The native library was a problem for me when I made an app that made a ton of AJAX requests[/quote]
And is above the 3rd party 'Native Session' lib?

My app does similar things, that's why I worry about that, read many posts which talk about lost sessions with out-of-the-box library, and I wanted to use 'Native Session' anyway, but that library seems not compatible with 1.7.2

I have read the wiki, and there I saw At the time of testing, this [Session Hybrid] is the only session libary that works correctly
http://codeigniter.com/wiki/Category:Lib...::Session/

That's why I ask. Edit: Thanks for your above quick reply!
#8

[eluser]sheldonnbbaker[/eluser]
Sorry - the native session library wasn't the problem for me - the CI one was. I haven't tried out any of the other ones available in the Wiki.

I actually made changes to the session library myself - I squashed that bug and removed the session data from the cookie (only the session ID lives in the cookie). I might put it up after I've tested it more thoroughly.
#9

[eluser]ciKD[/eluser]
Thanks for clarification.

So after a few days of research it looks like this for 1.7.2:

Based on the current thread and this posting and this open bug I can not use CI session (besides I comment out sess_update() and lose this security-feature), I can not use Native Session due to unclear compatibility in this thread, so I have to use Session_Hybrid, which unfortunately can not work without a database.

Edit: Reading on, I found in this thread that I would have to disable sess_update() only if it is an ajax-call, but the other newer postings above make me wonder it that's the solution.

I would like a Native Session like variant which plugs into CI, but without database but just using the php-built-in functions.

@sheldonnbbaker, which but did you fix in CI session?
#10

[eluser]sheldonnbbaker[/eluser]
I squashed the bug described here.

In my revised session library, I revised the sess_update() function to update add the old session ID (the one that was updated) into another column in the database (called 'old_session_id', for example). This value is held for 3 seconds or so. Then, during another request, sess_read() will look at both columns (session_id and old_session_id) to find matching session data.

This of course doubles the extremely minute chance that a session ID could be hijacked - but only for the few seconds that the old session ID exists (I clear it after 3 seconds or so).

My updated library also forces use of the database to store session data (the cookie holds only the encrypted session id).

I can email it to you if you'd like - but I haven't done any thorough testing on it, so you'd have to use it at your own risk Smile




Theme © iAndrew 2016 - Forum software by © MyBB