Resetting unverified session - ruby-on-rails

There are two servers, production.myapp.com and staging.myapp.com that use cookie session store and that cookie is set for myapp.com domain. Is there a way to handle a session cookie that can't be decrypted/verified? Rails version is 5.1.

Take a look at the Documentaion for Cookies. You can use an encrypted cookie and set the domain on the cookie to be myapp.com, i.e.
cookies.encrypted[:my-key] = {
domain: ".myapp.com",
secure: !Rails.env.development?,
value: "put-your-value-here",
}
Note however, that both apps will need to share the secret_key_base since that is what is used to encrypt / read the cookie value.
If you want to delete it be sure to pass the domain as argument.
cookies.delete(:my-key, domain: ".my-app.com")

Related

How to set cookie independently for each subdomain, causing different cookies?

I am developing a rails application that supports various subdomains. There is a root domain such as example.com and a user logs in through it and then redirects a user to specific subdomain url, group.example.com and users can jump between subdomain urls depending on which group they have access to. How to I set up domain attribute in session cookie so that it would not be available between subdomains (ex2.example.com and ex3.example.com)?
EDIT:
I am sorry I meant session cookies. I want to send different cookies for each subdomain urls.
Have a look at the documentation of the Cookie class. You can specify the domain when you create/delete the cookie.
cookies[:name] = {
value: 'a yummy cookie',
domain: 'ex2.example.com'
}
Of course, the value can be taken from the current request.
cookies[:name] = {
value: 'a yummy cookie',
domain: request.host
}
Here's the options
domain: nil # Does not sets cookie domain. (default)
domain: :all # Allow the cookie for the top most level
# domain and subdomains.
domain: %w(.example.com .example.org) # Allow the cookie
# for concrete domain names.
just add domain: my.subdoma.in to the cookie
btw: the user cookie should be available in all subdomains and you need to controller-check if he is having access to the group. this is the better way to do.

Change Rails session cookie domain without logging users out

I'm using Rails 4.2.2 (with Devise 3.4.1) and am changing the cookie_store domain from www.boundless.dev to .boundless.dev in order to share the same session across all of our subdomains (single sign-on).
Boundless::Application.config.session_store :cookie_store, key: '_boundless_session', domain: '.boundless.dev'
If I make this change alone. Existing logged-in users who return to the site will end up with 2 _boundless_session cookies, one with domain boundless.dev and the other with www.boundless.dev. Somehow this makes logging out impossible.
Is it possible to make this change without logging all users out of the site?
I thought that I'd be able to write a method as a before_filter in my ApplicationController to delete the session cookie and replace it with a new one at .boundless.dev, but it doesn't work, and I suspect it has something to do with the remember_user_token cookie.
def update_session_cookie_domain
session_cookie = cookies['_boundless_session']
cookies.delete('_boundless_session', domain: 'www.boundless.dev')
cookies['_boundless_session'] = {
value: session_cookie,
domain: '.boundless.dev'
}
end
I was able to solve this problem by changing the cookie name used for the session.
So the original config was:
Boundless::Application.config.session_store :cookie_store, key: '_boundless_session', domain: 'www.boundless.dev'
And I changed it to:
Boundless::Application.config.session_store :cookie_store, key: '_boundless_session_NEW', domain: '.boundless.dev'
I expected this to log users out, but it doesn't for some reason that I don't quite understand.
Unfortunately, I've yet to find a way to clear the old _boundless_session cookie, but at least now I can log out after having my session cookie updated to the more general domain.

Session across domains in Rails 4

I have an issue with wanting to use session across domains (not subdomain). Eg, I have .co.uk, .com.au, and .com all for the same address.
I know for subdomains I can use something like:
SomeApp::Application.config.session_store :cookie_store, key: '_some_app_session', domain => :all, :tld_length => 2
But I would like my solution to work between actually domains to have one set of sessions/cookies.
As your default session store is 'cookie_store'
You could just do it the same way as when you might send an email link with an authentication token. Check to verify that the cookie is correct on example.org and, if it is, redirect them to:
http://example.com?token=
and then check to make sure the token matches the one you have in the DB when they arrive. If the token does match, create the session cookie for the example.com domain and then change the token in the database.
This will successfully transfer from one domain to another while providing persistent login on the new domain (via cookie) and shutting the door behind them by changing the authentication token in the DB.
EDIT
To answer your question below, I don't think you need middleware or anything fancy. You could do a simple before filter in the application controller of example.org, something like:
before_filter :redirect_to_dot_com
...
def redirect_to_dot_com
url = "http://example.com" + request.fullpath
url= destination + (url.include?('?') ? '&' : '?') + "token=#{current_user.token}" if signed_in?
redirect_to url, status: 301
end
That will redirect the user either way, and append the token to the query if the user is signed in on the .org site.
Go to more details on Persisting user sessions when switching to a new domain name (Ruby on Rails)
I wouldn't use the PHP style routings which pass ?php=bad style variables via :get especially if you're already using sessions. And also since then you'd have to parse the original URL and a bunch of other work.
Instead of using session[:edition_id] = 'UK' you can use:
cookies[:edition_id] = { value: 'UK', domain: 'some-app.com', expires: 1.year.from_now }
# or if you want to be google 10.years.from_now
When you use session[:edition_id] = 'UK' the value will be encrypted by rails and stored in the _myapp_session cookie. But in your case that probably doesn't matter much.
If you set the cookie explicitly on the domain you want to read it from, it will work without having to set odd ball variables via get and then trying to interpret them again on redirect.

Rails 4 not encrypting cookie contents

Hello I'm trying to encrypt and secure the data contained in my cookies but It seems like the data only gets encoded (base64)
This is an example:
cookies.signed[:example] = { :value => 'can you see this?', :httponly => true, :expire_after => 30.minutes, :secure => true }
And this is the content of the cookie:
BAhJIhZjYW4geW91IHNlZSB0aGlzPwY6BkVG--b4a8bbd7cd35e392ccd788df0008fd10b48442b2
And if I decode the string (base64) I get:
I"can you see this?:EFom{q{vq{_M<}to8f
I would like to know what I'm missing, currently this is what I have in
session_store.rb:
Service::Application.config.session_store :cookie_store, key: '_service_session'
And in my secret_token.rb I have set something like this:
Service::Application.config.secret_key_base = 'e892d55cbc205bb6..'
Your cookis is not encrypted, because you used the signed method on the cookie jar, which, well, just signes the cookie content.
To encrypt the cookie, use the encrypted method:
cookies.encrypted[:discount] = 45
# => Set-Cookie: discount=ZS9ZZ1R4cG1pcUJ1bm80anhQang3dz09LS1mbDZDSU5scGdOT3ltQ2dTdlhSdWpRPT0%3D--ab54663c9f4e3bc340c790d6d2b71e92f5b60315; path=/
cookies.encrypted[:discount] # => 45
To piggy-back off of the accepted answer:
Depending on your situation: you might want to consider using a session cookie if you desire encryption. (As the accepted answer suggests: you can encrypt cookies, but perhaps a session cookie is more appropriate).
In rails 4 by default: the session cookie is by default encrypted and signed.
Relevant Rails Documentation.
Specific section:
If you only have secret_token set, your cookies will be signed, but not encrypted. This means a user cannot alter their user_id without knowing your app's secret key, but can easily read their user_id. This was the default for Rails 3 apps.
If you have secret_key_base set, your cookies will be encrypted. This goes a step further than signed cookies in that encrypted cookies cannot be altered or read by users. This is the default starting in Rails 4.
secret_key_base is located in rails 4 by default in: config/secrets.yml.
usage in rails 4:
# In rails 4 by default, this will be encrypted and signed
session[user_id] = 1

Can't understand sessions in Rails

Please don't bit my for my misunderstanding.
The sessions are very new for me, and i have some problems.
Okay i read many information about sessions and especially rails session. But this don't give me right imagine about sessions.
Did i understand right, when users send request to server (get) -> Server create a new session (and store this some file in hard drive with session id), session id -> is a random generated num? so, server create a new session (and store session on drive) after this server send back answer to client and set session_id in cookies?
Ok, i debug some params and see some results:
debug(session):
{:_csrf_token=>"jeONIfNxFmnpDn/xt6I0icNK1m3EB3CzT9KMntNk7KU=", :session_id=>"06c5628155efaa6446582c491499af6d", "flash"=>{}}
debug(cookies):
{"remember_user_token"=>"1::3GFRFyXb83lffzwPDPQd", "_blog_session"=>"BAh7CDoQX2NzcmZfdG9rZW4iMWplT05JZk54Rm1ucERuL3h0NkkwaWNOSzFtM0VCM0N6VDlLTW50Tms3S1U9Og9zZXNzaW9uX2lkIiUwNmM1NjI4MTU1ZWZhYTY0NDY1ODJjNDkxNDk5YWY2ZCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA==--348c88b594e98f4bf6389d94383134fbe9b03095"}
Okay, i know, what _csrf_token helps to prevent csrf.
session_id -> is id of the session which stored on hard drive (by default)
but what is _blog_session in cookies?
also, remeber_user_token containes my id (1::*) and what about second part, what is it?
Sorry for this stupid questions, i know what i can easy use any nice auth-plugins (authlogic/clearance/devise), but i want to fully understand sessions.
Thank you.
(also sorry for my english, this is not my native language)
remember_user_token is probably set by your authentication plugin, it is encrypted string, which is stored in users table and is used to authenticate him. Details can vary between plugins.
Second part: you are probably using cookie based session store (it is default),
So, _blog_session stores your encrypted session data.
More about cookie based sessions here and here.
The name "_blog_session" is set in config/initializers/session_store.rb
It looks like:
# Your secret key for verifying cookie session data integrity.
# If you change this key, all old sessions will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
ActionController::Base.session = {
:key => '_blogs_session',
:secret => '07fb6f0d41af4ae06aebb1696fcbb5a5398d4a08570744a4cd53ff237020c43a2022b4041d617d95bcf3f5c4601c7e6c1646eecfc157cc200e7dfedd7d7c6813'
}

Resources