rails / activerecord-session_store

Active Record's Session Store extracted from Rails
MIT License
547 stars 188 forks source link

What is the main purpose of this gem? #193

Closed wafendy closed 1 year ago

wafendy commented 2 years ago

Hi, may someone kindly explain what exactly this library does? What is the advantage of using this?

TIA

nflorentin commented 2 years ago

Hi @wafendy

I think this thread will help you to understand why this gem is useful : https://github.com/heartcombo/devise/issues/3031

TLDR: if you use cookie as session_store, this is no real logout, the cookie is still valid after the logout of the user, so if the cookie is stolen, authenticated requests can be made.

mockdeep commented 2 years ago

I am not an expert, but based on my reading it looks like if you're using force_ssl then cookies will be secure against session hijacking as well.

nflorentin commented 2 years ago

SSL make the cookie encrypted but it could be reused if you have it.

In Session Storage section of the doc, you can read :

Session cookies do not invalidate themselves and can be maliciously reused. It may be a good idea to have your application invalidate old session cookies using a stored timestamp

Without a gem like activerecord-session_store, you are not using a stored timestamp so the old session are not really invalidated. I could not believe it myself but I test it on my local machine and curl and it works, you can make "authenticated only" requests with a cookie after clicking on "Log out" if you are using cookie store as session store.

mockdeep commented 2 years ago

You can add timestamps to cookie based sessions as well. They're tamper proof unless your application key has been compromised. The important thing is not to trust the browser based expiration, but store your own timestamp in the session.

nflorentin commented 2 years ago

Ok thanks for your explanation but how do you explain that cookie can still be used after a log out on fresh rails/devise setup with cookie store as session store ?

Here a reply from a developer of devise: https://github.com/heartcombo/devise/issues/3031

What do you need to do to avoid that without using another store ?

mockdeep commented 2 years ago

@nflorentin I am going to preface this by saying I am not a security expert so all of this is to the best of my understanding.

Regarding the issue you link, I have never seen an issue where the user is still logged in after the session is cleared and they are redirected. I would be interested to see code that reproduces the issue. I have seen cases where the user has been able to click back in the browser and they're logged in again. One thing we do in our app is to disable the browser cache entirely to prevent somebody clicking back in the browser and getting a stale page:

response.headers['Cache-Control'] = 'private, no-store'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = 'Fri, 01 Jan 1990 00:00:00 GMT'

At any rate, that issue is from eight years and 3 major Rails versions ago, so it may not still be relevant.

We actually tried transitioning to AR-SS for a bit but it caused major test flake for us where sessions weren't persisting properly for some reason. We didn't get any issues reported by users, but that was a big red flag for us. I'm inclined to go with the better supported built-in solution for session storage. AR-SS doesn't address all of the security issues related to sessions, anyway, so you'd need to build around them yourself. For example, you still need to add logic to handle session timeouts, deleting or invalidating sessions in the db.

What we may end up doing is adding our own session_data table that can track whether a session is still valid, while still keeping the session contents in the cookie. This avoids the complexity of trying to tie into the built-in rails session behaviors. It is also a good way to provide users a view of their active sessions across devices, and allow them to revoke sessions.

nflorentin commented 2 years ago

@mockdeep Thanks for your answer.

I was like you when I first saw the issue, I could not believe that the "issue" was still here after years.

I tested it myself and you can do it in 2 minutes :

I tested it on various applications which used cookie store as session store.

mockdeep commented 2 years ago

@nflorentin it's important to remember that curl is not your browser. Yes, if you have a copy of an old cookie you can re-use it. However, to my knowledge, browsers don't keep around old versions of cookies. They replace the cookie with whatever the server sends back in the response. So unless your browser or computer is compromised, I don't think it's a risk. And if your computer is compromised, then it's probably the least of your worries. At that point, the attacker can get your credentials or pretty much anything else they want, so they don't need a cookie.

That's not to say you shouldn't try to address it, but you should weigh it against other security threats and prioritize the cases that are higher risk. For my own part, I think it's important to have sessions expire (via an external mechanism) in a reasonable amount of time (e.g. 2 weeks) and require 2FA so that even if somebody does gain access, either via a stolen cookie or credentials, they can only access it for a limited time. Even with AR-SS, an attacker can continue to use a stolen cookie so long as the user hasn't logged out.

nflorentin commented 2 years ago

@mockdeep I totally agree with you.

As you say it is not a very important vulnerability. I realized it only after years of coding with rails, because one of my app has a security audit done by an external company. It was ranked as medium security risk by the audit.

I installed this gem because it seems to fix the issue and was very little effort.

Thanks for the interesting discussion :)