Safe and Insecure Sessions with Rails

I have an e-commerce site where, when a user logs in, they can make a purchase with saved credit card information. So, I want to use a secure session.

However, I have non-SSL pages on the site, and the user must also be registered on these pages. Therefore, I also want to conduct an unprotected session for this user.

How to do it with Rails?

+4
source share
2 answers

You correctly understood that the problem with mixing HTTP and https in a standard Rails application is that the session must be insecure (i.e. link through an insecure cookie), which means that it is vulnerable to a session failure.

As you mentioned in your comment on @nmott's answer, one approach is to have both a safe and an insecure cookie.

Instead of referring to two identical sessions, for my purposes, I consider it sufficient to have an unsafe Rails session along with a secure, signed cookie that simply refers to the user_id of the current user. In other words, I don’t need a full copy of the session, something unique for each user (in a secure cookie) that corresponds to an insecure session.

In every action that is accessed via SSL (and has the current user), I verify that the secure signed cookie user_id matches the user ID stored in the insecure Rails session. If there is a coincidence, I assume that everything is fine, and act normally, referring to an insecure session. If there is no match, an error message appears. I accomplish this with the before_filter method, such as:

def verify_secure_user_cookie # If we have a current user and the request is SSL, we want to make sure the user # has a secure cookie that matches the current user id. This prevents attackers # from side-jacking a session by obtaining a cookie from a non-SSL request. if current_user and request.ssl? unless cookies.signed[:user_id] == current_user.id raise StandardError, "Invalid secure user cookie" end end end 

Presumably, a legitimate user will always have a secure cookie and they will never see an error message. An attacker will be able to copy an insecure cookie and will not have access to a secure cookie. In this case, he could connect to the session and access non-SSL pages, but he could not access the SSL pages using the victim's session.

Thus, your non-SSL pages are still vulnerable to lateral connectivity, but your SSL pages are not vulnerable to session failures. For this to be effective, you need to enforce SSL for all actions that need to be protected (either from eavesdropping or from session failures). Using force_ssl in a controller is one way to do this, or you can roll your own.

+5
source

In rails, you can force SSL for any controller:

 force_ssl 

This automatically redirects any http call associated with the controller action to https . This is separate from any authentication that will be implemented as you want.

Simply authenticate for the controllers that require it, including non-ssl controllers, and use force_ssl for any controllers that additionally require a secure session.

+3
source

Source: https://habr.com/ru/post/1396081/


All Articles