Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sessions are getting crossed. Ruby on Rails

I have an app that is using devise for authentication. Rails 3 on ruby 1.9.2, with passenger on top of nginx.

Here is my problem: I have noticed that occaisionally my sessions are getting crossed. While being logged in as one user, I sometimes become another user. This is really a horrible problem. I have managed to get it to stop by using active_record sessions storage. But I am stumped as to where it could be happening. It happens both when using cookie storage, and memcached storage. I am not sure where to start debugging. I have gone through all of my code, and I am only reading from 'current_user' not writing. I don't have any code storing items in session.

Can anyone give me suggestions as to where, or how this could be happening?

Update:

I setup a div at the top of the page to dump the session contents on each request. It is not just the user switching, it is the whole session. There are some dummy variables that I set in the session just to see what would happen. When the sessions get crossed, (User A becomes User B) User A now sees the dummy variables that User B had. And User B is logged out.

UPDATE 2

I found another question here on stack overflow that describes the same exact problem: In Rails, what could cause a user to have another user's session?

It looks like it could be a passenger issue? But more important, how come it is even happening? This is a REAL big problem. How do I put a stop to this?

UPDATE 3

I am now using Unicorn to serve my app. I set config.threadsafe! and started using active-record sessions exclusively. No more memcached sessions. The problem is gone. At least I can stop pulling my hair out because the security hole is plugged.

I would still like to know what exactly was causing it. Most of the tutorials out there show how to setup passenger, with the default spawning method. Naturally, I would think memcached would perform best for session management over the other methods. Especially in a multiple application server environment.

Update 4

Okay, last and final update. This was an issue with forked processes using the same memcached connection. I fixed it by using dalli memcached client, and reseting the connection in the after_fork callback of either unicorn or passenger.

like image 781
demersus Avatar asked Jan 21 '11 03:01

demersus


People also ask

How session works in Ruby on Rails?

Each time a request hits Rails app, Rails retrieves the session ID from the cookie, gets the serialized session associated with that session ID from Redis, and deserializes that into a hash. That hash is what the method session returns.

Where sessions are stored in Rails?

Rails store it in server side. Session is saved in server side like key value pair (like json object)

Are Rails sessions encrypted?

Rails uses encryption to securely prevent tampering with the session contents, however, users cannot revoke sessions because the contents are stored on the browser.

What is session and cookies in Rails?

Cookies, Sessions and Flashes are three special objects that Rails gives you in which each behave a lot like hashes. They are used to persist data between requests, whether until just the next request, until the browser is closed, or until a specified expiration has been reached.


1 Answers

I'd be willing to bet you're using Passenger's (default) smart spawning, and falling victim to the Spawning Gotcha.

Set your PassengerSpawnMethod to 'conservative' and see if this goes away. This easily accounts for the memcache case, unless you are protecting against it. Presumably a similar problem in devise (or your code).

Do you see sessions cross across physical servers, or only on one server?

like image 150
user510365 Avatar answered Oct 13 '22 16:10

user510365