session_store :active_record_store options - ruby-on-rails

Wanted to know the meaning of the :secret and :key options while configuring the session_store. So, for example I have a config like the following:
MyApp::Application.config.session_store :active_record_store,
{:key => '_my_app_session', :secret => '5xb5x1g92e965b95b16e49x79gxx9999', :expire_after => 2.hours}
what would the :secret and :key options do here? I googled but not many answers.
Thanks

I'm pretty sure those options are only valid if you're using the cookie session store (rather than the active record session store). The key is the name of the cookie which contains the session data, and the secret is the value used to encrypt/decrypt the data stored in the cookie.

Active Record Session Store:
"The serializer may be one of marshal, json, or hybrid. marshal is the default and uses the built-in Marshal methods coupled with Base64 encoding. json does what it says on the tin, using the parse() and generate() methods of the JSON module. hybrid will read either type but write as JSON."
Adding: ActiveRecord::SessionStore::Session.serializer = :json to config/application.rb solved the issue for me.

Related

how to get the persistent cookie value and session cookie value in rails application

Im developing ruby on rails application. I want to get the persistent cookie value and session cookie value in the application. Can any please guide me on this
I have read that request.session_options[:id] will fetch the session_id, is that the one that is usually stored in session cookie? Please guide me if my way of understanding is wrong.Thanks in advance
In Rails, it is simple as calling the session or cookies hash.
# Set a simple session cookie
cookies[:user_name] = "david"
# Read a cookie
cookies[:user_name] # => "david"
# Delete a key
cookies.delete :user_name
The same goes for session.
So, the information that you are looking for is probably inside one of these two.
Take a look at the examples at http://www.tutorialspoint.com/ruby-on-rails/rails-session-cookies.htm

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

Storing an encrypted cookie with Rails

I need to store a small piece of data (less than 10 characters) in a cookie in Rails and I need it to be secure. I don't want anybody being able to read that piece of data or injecting their own piece of data (as that would open up the app to many kinds of attacks). I think encrypting the contents of the cookie is the way to go (should I also sign it?). What is the best way to do it?
Right now I'm doing this, which looks secure, but many things looked secure to people that knew much more than I about security and then it was discovered it wasn't really secure.
I'm saving the secret in this way:
encryptor = ActiveSupport::MessageEncryptor.new(Example::Application.config.secret_token)
cookies[:secret] = {
:value => encryptor.encrypt(secret),
:domain => "example.com",
:secure => !(Rails.env.test? || Rails.env.development?)
}
and then I'm reading it like this:
encryptor = ActiveSupport::MessageEncryptor.new(Example::Application.config.secret_token)
secret = encryptor.decrypt(cookies[:secret])
Is that secure? Any better ways of doing it?
Update: I know about Rails' session and how it is secure, both by signing the cookie and by optionally storing the contents of the session server side and I do use the session for what it is for. But my question here is about storing a cookie, a piece of information I do not want in the session but I still need it to be secure.
Setting a secure cookie
cookies.signed[:secret] = {
:value => "foo bar",
:domain => "example.com",
:secure => !(Rails.env.test? || Rails.env.development?)
}
Accessing the cookie
cookies.signed[:secret] # returns "foo bar"
The cookie is signed using ActionController::Base.cookie_verifier_secret. You can set the cookie_verifier_secret in the initializer file.
As KandadaBoggu says, it looks like what you want is a session variable, and session variables are by default encrypted and stored in cookies. However, if you have a look at the contents of config/initializers/session_store.rb you will find something like the following:
# Be sure to restart your server when you modify this file.
MyRailsApp::Application.config.session_store :cookie_store, :key => '_my_rails_app_session'
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# MyRailsApp::Application.config.session_store :active_record_store
Which suggests to me that you should use the database for sessions instead of the cookie-based default, which shouldn't be used to store highly confidential information. The pre-cooked migration makes everything really easy to set up so there's very little overhead in doing so, and once it's done there's basically zero overhead if you need to add a new piece of secret information at a later date!
I'm re-posting JacobM's answer, that he deleted, because it was the correct answer and pointed me in the right direction. If he undeletes it, I'll delete this one and pick his as the best answer.
First of all, if you use encrypt_and_verify instead of encrypt it will
sign the cookie for you.
However, when it comes to security, I always prefer to rely on
solutions that have been vetted in public, rather than rolling my own.
An example would be the encrypted-cookies gem.

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'
}

Accessing the "session key" cookie name from anywhere in Rails

We are building a plugin for Rails to be used within iframe Facebook applications, and at one point we need to check if Rail's session id cookie as been set or not.
By default, this cookie is named _myprojectname_session, what we need to find out is the actual name of the cookie itself. So if it's not set, we can do some redirects to make sure the cookies are set.
How do we access the damn name of the cookie from anywhere? Or at least from within a controller?
Rails.application.config.session_options[:key]
I found the solution. In Rails 2.3.2 at least the session key in set in config/initializers/session_store.rb like this:
ActionController::Base.session = {
:key => '_myapp_session',
:secret => '[...]'
}
And you can read the value like this:
ActionController::Base.session_options[:key]
From Base.session to Base.session_options automagically, doesn't make much sense, and it caused me a big headache... lol
To access the name of the session cookie from within the view or the controller, you can say:
request.session_options[:session_key]
and then to access the raw value of that cookie, being an empty array if it's not set, you use:
request.cookies[ request.session_options[:session_key] ]
The cookie name ( aka session_key ) is set in your config/environment.rb file.
config.action_controller.session = {
:session_key => '_project_session',
:secret => 'long-secret-key'
}
In my experience, if there is an underscore in the key, IE SOMETIMES does not set the cookies. In other words, use 'projectsession' instead of '_project_session'.
I think that the session key is stored in a variable called ENV_SESSION_KEY
Note also this bug which affects tests around session_options in some versions of Rails 2.x: https://rails.lighthouseapp.com/projects/8994/tickets/2303-testrequest-doesnt-initialize-session_options
In Rails 3/4 I'm using this:
request.env["rack.request.cookie_hash"]
This is a hash that contains all the cookies for current user including the one for session.
The hash has as a key the name of the cookie, and as a value the value of the cookie
I couldn't work out how to do this in rails 3 :-(
Eventually I ended up putting this in config/initializers/session_store.rb
SESSION_KEY = '_myapp_session'
MyApp::Application.config.session_store :cookie_store, :key => SESSION_KEY
and then accessing this where needed, eg in a view...
<%= ::ENV_SESSION_KEY %>

Resources