Rails, CookieStore vs ActiveRecordStore - ruby-on-rails

I am currently experiencing a strange issue with our users being logged out. I haven't been able to reproduce it explicitly.
The Rails application is using the default CookieStore.
My initial hypothesis is that somehow the session data within the cookie, or even the cookie itself is being destroyed. This may be either from a user clearing browser data, or something within the system that has not been caught.
As of now, the authentication system appears to be functioning as intended (Authlogic), and we are not experiencing the issue wide-spread in other components of the application.
I am considering using ActiveRecordStore to see if the problem is resolved. My understanding is the session data would be stored within the database, and if a cookie was being removed - the user would not get logged out.
Are there many known pros/cons to using CookieStore vs ActiveRecordStore?
Why is CookieStore the default when creating a Rails application, and not ActiveRecordStore?

I can answer your last two questions.
You should not use the cookie store if you're storing sensitive data in the session because you want such data to be on the server-side and not on the client.
The cookie store is the default because Rails is giving you a strong hint that you should not be storing lots of data in the session, by virtue of the fact that cookie storage is limited to 4 KB.

I think CookieStore is the default because it is simple. It doesn't require a database table.
CookieStore is not as secure as ActiveRecordStore. With CookieStore, intercepted cookies will give access to a valid session forever, even if you create a new one. With ActiveRecordStore, you can invalidate a session by removing it from the database.
See this blog post: http://www.bryanrite.com/ruby-on-rails-cookiestore-security-concerns-lifetime-pass/

Related

Rails app with different session store for each model

I have two models doing login (Devise) in my Rails app - Admin and User, both currently use the default cookie store for session data.
I want to be able to identify an Admin session in AJAX requests coming in from the admin, for authorization of these API calls. I plan to do this by setting an encrypted cookie upon Admin login. When the AJAX API call comes in, I open the cookie, grab some identification from it and look for a matching existing Admin session in the store.
As I understand it, to do this, I must have session information stored in the back-end, either by DB or memcache stores.
I expect to have millions of sessions of Users and just a few sessions of Admin at any given time. For this reason, I don't want to just move all session information to a DB or memory, since this is a heap of unneeded data to store. I only want to store/look at Admin session data.
A solution will be creating some custom model which enumerates Admin user sessions, and is maintained by the app. This is simple enough but requires for instance, a way to clean up sessions when they die without signing out. Essentially this is an attempt to duplicate Rails's session store mechanism, which comes with all the problems of storing and maintaining sessions. Instinct tells me to avoid this solution. Am I correct to avoid it?
If so, then my question is, is there a way to configure multiple session stores in a Rails app, a different store for every logged in Model? In this case, have Admin sessions stored in memory, and User sessions stored in cookie. If not, I'll greatly appreciate any comments and suggestions.
Thanks!
You may be thinking about it wrong.
Session are a low level mechanism that you build your authentication on top of. Its just a cookie containing an identifier (a random hash) which is linked to a session storage (by default cookies). This is a simple mechanism to add persistence to a stateless protocol.
Confusingly we also use the concept "sessions" when talking about authentication - for example logging a user in is often referred to as "creating a session". This is complete poppycock as we are just storing a claim (often a user id) in the session that was created when the user first visits the application.
If so, then my question is, is there a way to configure multiple
session stores in a Rails app, a different store for every logged in
Model?
No. Thats a chicken-vs-egg conundrum. In order to know which session storage to use you would need to access the session storage to know which session storage to use... you get the picture.
While you could create your own session storage mechanism that works differently does this is most likely a complete waste of time. Premature optimization is the root of all evil.
As I understand it, to do this, I must have session information stored
in the back-end, either by DB or memcache stores.
Not quite true. You can perfectly well build an authentication solution with just the cookie storage. In that case Rails just keeps a record on the server of which session identifiers are valid.
The main reason you would need to store additional session information in the database or memcached is if you need to store more data in the session than the 4093 bytes allowed by a cookie. Cookie storage is after all much faster and does the job fine 99% of the time. YAGNI.
You should also recognize that not everything needs to be saved in the session storage. For example the Devise trackable module saves log in / out timestamps on the user table as part of the process of authenticating a user. This is "session information" yet has nothing to do with session storage.
I want to be able to identify an Admin session in AJAX requests coming
in from the admin, for authorization of these API calls.
There are many ways to use different authentication logic for different parts of the application such as Warden strategies. For an API you may want to consider using stateless (and sessionless) authentication such as JWT.

How does rails/devise handle cookie sessions?

I'd like to understand what's really going on when signing in a user with rails/devise.
I've created a minimal rails app, installed devise and created a User devise model.
Everything works fine, and when I log in (using remember me) I get a session cookie just as expected.
Now what's bugging me is : How does rails handle the session informations that the browser is passing through the cookie ?
I'd naively expect some information to be stored in the database, but I don't see where. There's no such thing as session table, no session column in Users, and I couldn't find anything of interest in the tmp dir.
Note that restarting the server wouldn't kill my session. It is of course expected, but now I'm really wondering what kind of magic is happening here ?
in other words : how does the server check the validity of a cookie to authenticate a user ?
Thanks !
The default rails session storage is CookieStore. This means that all the session data is stored in a cookie rather than in the database anywhere. In Rails 3.2 the cookie is signed to prevent tampering, but not encrypted. In Rails 4 it's generally encrypted by default. The fact that it's in a cookie is how it persists across restarts of your server. It also means you can only store 4k of data and you wouldn't want to store anything sensitive in there in Rails < 4. It's best to keep a minimum of data in the session anyway.
You can also opt for storing the session data in the database and only having a session id in a cookie.
This answer I gave the other week has some extra info that might be useful:
Sessions made sense to me before I started reading about them online
Also, the rails api doc for CookieStore gives a nice summary:
http://api.rubyonrails.org/classes/ActionDispatch/Session/CookieStore.html

Does Ruby on Rails lock user sessions?

I'm coming from PHP background and have a question regarding RoR user sessions. By default PHP uses file storage with write locks for user session data. So it prevents processing of multiple requests by the same client at the same time. How does RoR behaves with sessions?
The default session store in rails store the entirety of the session data in the session cookie itself (known as the cookiestore).
One side effect of this is that if 2 overlapping requests both try and update the session then the last one to send a response back to the client 'wins'.
I don't think any of the session stores commonly in use with Rails have the concurrency property you describe.

Rails v2.3 : Difference between session and cookies

I am learning Rails by reading the online guide(for Rails v2.3). The guide is great, however, there is a confusion for me, that's:
there is a chapter explains the Session of Rails and another chapter explains Cookies of Rails. The explanation is easy to understand separately, but when compare the two, reader like me does not see the significant difference between Session and Cookies . Especially under which situation session should be used and under which situation Cookies should be used ?
Besides, in the session chapter, there is a concept of CookieStore , what is the difference between the CookieStore and Cookies then?
Could someone explain to me these?
Sessions & Cookies both hold the ability to store some information (e.g : the current_user id) in between two or more requests which (in http) are otherwise stateless.
But Session is more of an abstract concept related to the notion of being in a certain state for a specific amount of time : the info it contains can be stored in the database, in a server side file, in a redis hash OR in a cookie.
Cookies are always the little text file navigators have to store some persistent data in between requests... But having some data on the client side can be insecure so that's why it is often encrypted. But it's true the notion can overlap with session.
TL;DR : session the abstract concept of holding temporary data. Cookies one (common) way of doing it.
A cookie is a small text file stored in the browser.
A session is the concept of a state of being "in-use", and that state can have data associated with it. Rails keeps track of sessions with cookies, and lets you choose different storage for associated data and access it with the same session interface.
CookieStore means all the session information is stored inside the cookie itself. You can choose to use various other stores where appropriate, and it'll still be available with your session accessor methods.
In addition to the session, you can set other cookies to store information on the user's browser. These are not tied to the session and can be set, accessed and deleted independently.
Example 1, storing a logged-in user's shopping cart in a session:
session[:embarassing_products] = ['ooh',
'naughty',
'lucky_im_using_activerecord_store',
'only_the_session_id_is_in_the_cookie',
'other_data_arent_in_the_browser']
The shopping cart is preserved for the user's session. You can set the session to end when the browser window is closed, when the user logs out, or when a certain amount of time passes.
Example 2, remembering a browser's last language preference for your domain in a cookie:
cookie[:lang] = 'en-US'
This information is stored inside the cookie itself. Unless the cookie expires or is deleted (by you or the user), it stays inside the browser.
As to me the main difference is that the session data stored on the server, whereas the cookies are stored on the client (browser).
So you can trust the data from the session. Information from the cookie can be manipulated, stolen, and thus should not be relied on for critical use (for right access for example).
Second point, is that cookies have a limited size, and are only text-based. You can store in session many complex objects (but beware of memory consumpation), and you don't have to transfer them to client then back at each request.
And typically the session only persists until the user shuts down their browser. That's useful for typical logins. Whereas if you needed information to persist between sessions you could use a cookie with a longer duration, for example a 'remember me' flag that persists even after the browser is restarted.

Difference between CookieStore Sessions and Encrypted Cookies in Ruby On Rails

I was wondering whether there is any difference between a session and an encrypted cookie (configured to expire as the session cookie does).
Aren't they the exact same thing? Or Rails provides extra security for sessions?
A session is a higher-level thing than a cookie. Sessions are collections of variables which persist for one user session only. Sessions can be stored in a cookie, in a database, or wherever a session-handling plugin chooses to store them. Cookies are now the default place where sessions are stored in modern versions of Rails. Note: when sessions are stored outside the cookie, there's an ID stored in the cookie so Rails can look up the session data in wherever it's stored (e.g. a database).
Now, let me move on to what I think you want to be asking: what's the difference between Rails' default session-storage (which uses an un-encrypted cookie) and Phusion's EncryptedCookieStore or any other encrypted-cookie session storage implementation? Why do you care about encrypting a session cookie?
According to http://agilewebdevelopment.com/plugins/encrypted_cookie_store, here's the crux of the difference: "EncryptedCookieStore is similar to Ruby on Rails's CookieStore (it saves session data in a cookie), but it uses encryption so that people can't read what's in the session data. This makes it possible to store sensitive data in the session.".
Note that there are multiple different EncryptedCookieStore's. AFAIK, you's want to use Phusion's EncryptedCookieStore and not ThinkRelevance's older EncryptedCookieStore.
If you're not encrypting cookies, then session data is easily readable by anyone with access to the cookie (either via network sniffer, disk access to the client, XSS, etc.) For details about how session vars are stored into cookies (along with security implications), look here: http://www.neeraj.name/2009/05/04/how-cookie-stores-session-data-in-rails.html.
Note that the default (non-encrytped) cookie storage is tamper-resistant (meaning Rails will reject a maliciously changed cookie). So if all you're worried about is preventing people from changing your cookies (but don't care if they see your cookies) then you're OK with the default.

Resources